<?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>Forem: Kannav Sethi</title>
    <description>The latest articles on Forem by Kannav Sethi (@kannav02).</description>
    <link>https://forem.com/kannav02</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1713295%2F3d1e2d74-b7a2-426b-a723-a771b83101f9.png</url>
      <title>Forem: Kannav Sethi</title>
      <link>https://forem.com/kannav02</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kannav02"/>
    <language>en</language>
    <item>
      <title>Reflecting on the ORAssistant Project: A Journey of Collaboration and Technical Growth</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Sat, 07 Dec 2024 04:32:01 +0000</pubDate>
      <link>https://forem.com/kannav02/reflecting-on-the-orassistant-project-a-journey-of-collaboration-and-technical-growth-56i0</link>
      <guid>https://forem.com/kannav02/reflecting-on-the-orassistant-project-a-journey-of-collaboration-and-technical-growth-56i0</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;If you've been following my last two blogs, you already know the context of this project. This is the final installment of a three-part series documenting my journey with the OpenROAD Project's ORAssistant. If you missed the previous entries, I recommend checking out those blogs to get the full background on this exciting open-source contribution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kannav02/planning-to-resolve-automatic-feedback-loop-4fgd"&gt;blog1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kannav02/progress-on-automatic-feedback-loop-1e43"&gt;blog2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first stumbled into the world of the OpenROAD Project's ORAssistant, I had no idea how much I'd learn. What started as a simple desire to contribute turned into a rollercoaster of technical challenges.&lt;/p&gt;

&lt;p&gt;The first challenge was understanding the existing system. I spent hours poring over the code, trying to figure out how the current feedback mechanism worked. It was like solving a puzzle where each piece was slightly more complicated than the last.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;The core of my technical work involved creating a MongoDB-based feedback submission system. This required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Carefully analyzing existing feedback submission mechanisms&lt;/li&gt;
&lt;li&gt;Designing a prototype function mirroring the Google Sheets integration&lt;/li&gt;
&lt;li&gt;Developing and refining a &lt;code&gt;validator schema&lt;/code&gt; for the &lt;code&gt;context&lt;/code&gt; collection&lt;/li&gt;
&lt;li&gt;Debugging and improving the &lt;code&gt;submit_feedback&lt;/code&gt; function in &lt;code&gt;mongoClient.py&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these steps wasn't just a technical task – it was a learning journey, a chance to understand not just how code works, but why it works the way it does.&lt;/p&gt;

&lt;h1&gt;
  
  
  Challenges Faced
&lt;/h1&gt;

&lt;p&gt;Remember those minor issues that can drive a developer crazy? I had plenty. My &lt;code&gt;validator schema&lt;/code&gt; for the &lt;code&gt;context&lt;/code&gt; collection was a mess at first. And the &lt;code&gt;submit_feedback&lt;/code&gt; function? It was returning &lt;code&gt;None&lt;/code&gt; like a stubborn child, throwing &lt;code&gt;error&lt;/code&gt; messages even when everything seemed correct.&lt;br&gt;
But the real kicker was the &lt;code&gt;CI&lt;/code&gt; pipeline issue. Picture this: I'd crafted what I thought was a perfect pull request, only to have it shut down because of secret propagation problems. Talk about frustrating!&lt;/p&gt;

&lt;p&gt;The frustration was real. But so was the learning.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Community That Saved Me
&lt;/h1&gt;

&lt;p&gt;This is where the magic of open-source really shines. The project maintainers weren't just gatekeepers – they were problem-solvers. They granted me repository access, offered guidance, and showed me that open-source is as much about people as it is about code.&lt;/p&gt;

&lt;h1&gt;
  
  
  What I Learned (Beyond Code)
&lt;/h1&gt;

&lt;p&gt;Sure, I picked up some technical skills. MongoDB integration? Check. CI/CD troubleshooting? Got it. But the real lessons were deeper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patience is more than a virtue; it's a necessity in software development&lt;/li&gt;
&lt;li&gt;Every error is an opportunity to learn&lt;/li&gt;
&lt;li&gt;Communication is the real programming language&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;To anyone thinking about contributing to open-source: do it. It's messy, it's challenging, and sometimes it'll make you want to throw your computer out the window. But trust me, the rewards are worth every moment of frustration.&lt;/p&gt;

&lt;p&gt;I've said this previously as well ,  but I love open-source and all of this was really a good experience for me&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>github</category>
      <category>rag</category>
    </item>
    <item>
      <title>Progress on Automatic Feedback Loop</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Fri, 29 Nov 2024 02:28:32 +0000</pubDate>
      <link>https://forem.com/kannav02/progress-on-automatic-feedback-loop-1e43</link>
      <guid>https://forem.com/kannav02/progress-on-automatic-feedback-loop-1e43</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;This blog will elaborate on my progress towards contributing to the &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant/issues/75" rel="noopener noreferrer"&gt;Automatic Feedback Loop&lt;/a&gt; on the repo &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant" rel="noopener noreferrer"&gt;ORAssistant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to know more about these you can have a look at my &lt;a href="https://dev.to/kannav02/planning-to-resolve-automatic-feedback-loop-4fgd"&gt;previous blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well this repo has given me a lot of good experiences, I will briefly discuss some of them over here&lt;/p&gt;

&lt;h1&gt;
  
  
  Integrating the MongoDB function for feedback
&lt;/h1&gt;

&lt;p&gt;Now in the first PR that I made to this repo, I proposed a design for MongoDB, &lt;/p&gt;

&lt;p&gt;In this PR, I am integrating the functionality to submit the feedbacks that the user is getting to the MongoDB collections&lt;/p&gt;

&lt;p&gt;My approach was as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the existing functionality to find how the parameters were being passed to the google sheets function&lt;/li&gt;
&lt;li&gt;Create a prototype function following a similar logic to the Google Sheets function&lt;/li&gt;
&lt;li&gt;Test it out with dummy data from the frontend&lt;/li&gt;
&lt;li&gt;Check if the data is being loaded to the MongoDB collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now this approach actually succeeded but with one major issue and a couple of minor issues&lt;/p&gt;

&lt;p&gt;The minor issues were as follows :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My validator schema for the &lt;code&gt;context&lt;/code&gt; collection was wrong and because of this my data was not being sent to the collection, &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;submit_feedback&lt;/code&gt; function in &lt;code&gt;mongoClient.py&lt;/code&gt; file was returning None in all the cases, thus leading to error messages even when the result was correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will talk about the major issue in the next point&lt;/p&gt;

&lt;h1&gt;
  
  
  Fork Issue
&lt;/h1&gt;

&lt;p&gt;The major issue that I encountered while submitting a PR was that even though all of my new code in the PR was correct, the CI pipeline wasn't accepting any new PRs due to the fact that the secrets from the &lt;code&gt;upstream&lt;/code&gt; repo were not propagating to the fork repo, thus the CI pipeline was failing&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4szh3q1u92jumpdzxtct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4szh3q1u92jumpdzxtct.png" alt="Image description" width="642" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seeing this issue, the maintainer did grant me the read/write permissions to contribute to the repo , and I did so.&lt;/p&gt;

&lt;p&gt;I volunteered to fix this issue and correct the pipeline as not correcting it would lead to all of the potential new contributors having read/write access to the repo which isn't good&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;my journey with the ORAssistant repo has been an insightful learning experience. Integrating the MongoDB function for feedback has not only enhanced my technical skills but also provided valuable insights into database handling and testing. Although the initial implementation was successful, addressing the encountered issues helped me refine my approach. Moving forward, I plan to continue building on this foundation and contribute further to the project, ensuring smoother functionality and better user experience.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>Planning To Resolve Automatic Feedback Loop</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Wed, 27 Nov 2024 02:27:02 +0000</pubDate>
      <link>https://forem.com/kannav02/planning-to-resolve-automatic-feedback-loop-4fgd</link>
      <guid>https://forem.com/kannav02/planning-to-resolve-automatic-feedback-loop-4fgd</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;One of the things that I have learned during my Open-Source Journey, is that this domain is filled with experiences, which will not only level up my skills as a Developer but would also give me a chance to work on technologies that I would've worked at a Big Company&lt;/p&gt;

&lt;p&gt;To broaden my horizon of tech-stack, I looked out for another issue that would enhance my skills as a Developer, I saw this repository called &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant" rel="noopener noreferrer"&gt;ORAssistant&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  Why this Repo
&lt;/h1&gt;

&lt;p&gt;I have always wanted to work on AI applications that are industry standard or have industrial standard designs, and this repository is a RAG-based application&lt;/p&gt;

&lt;p&gt;At first glance over this repo, I knew it was a match made in heaven, the amount of details that the maintainers have highlighted in the architecture of this application is gigantic. &lt;/p&gt;

&lt;p&gt;This is one of the diagrams explaining the architecture&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6s2rkngyw8v16m8iqoz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6s2rkngyw8v16m8iqoz.png" alt="Image description" width="744" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have always wanted to see how the designs behind such apps look like&lt;/p&gt;

&lt;p&gt;This was my first time seeing a design like this and I loved it.&lt;/p&gt;

&lt;p&gt;All in all, my passion for learning more about AI design was the one that attracted me to this project&lt;/p&gt;

&lt;h1&gt;
  
  
  Issue and My Approach
&lt;/h1&gt;

&lt;p&gt;I have talked about the issue in one of my &lt;a href="https://dev.to/kannav02/contributing-to-orassistant-22o2"&gt;previous blogs&lt;/a&gt;, you can go and check it out for a comprehensive overview of the issue that I am dealing with&lt;/p&gt;

&lt;p&gt;For this issue, my first PR for this project was to deal with the MongoDB design, again I have given a comprehensive report for the same in my &lt;a href="https://dev.to/kannav02/contributing-to-orassistant-22o2"&gt;previous blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am working on getting my second PR merged which is related to adding the MongoDB functionality to the existing Feedback functionality,&lt;/p&gt;

&lt;p&gt;My approach to this is to add to the existing functionality without breaking the previous code and testing it out to see if it's working as expected&lt;/p&gt;

&lt;p&gt;This is my second PR contribution to this project and so far I have loved every moment of it, there's just too many things to learn and develop&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Contributing to the ORAssistant project has been a remarkable learning experience that aligns perfectly with my passion for AI design and development. It has not only deepened my understanding of industry-standard architectures but also allowed me to tackle real-world challenges. This journey has truly reinforced my enthusiasm for open-source development and its ability to foster growth and innovation.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>ai</category>
      <category>rag</category>
    </item>
    <item>
      <title>Contributing to ChatCraft</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Sat, 23 Nov 2024 04:07:20 +0000</pubDate>
      <link>https://forem.com/kannav02/contributing-to-chatcraft-2n61</link>
      <guid>https://forem.com/kannav02/contributing-to-chatcraft-2n61</guid>
      <description>&lt;h1&gt;
  
  
  Adding API Key Management for Non-LLM AI Providers in ChatCraft
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog post, I'll discuss my recent contribution to &lt;a href="https://github.com/tarasglek/chatcraft.org" rel="noopener noreferrer"&gt;ChatCraft.org&lt;/a&gt;, where I implemented support for non-language model AI providers, specifically focusing on Jina.ai integration for PDF to Markdown conversion. This work was done as part of &lt;a href="https://github.com/tarasglek/chatcraft.org/pull/740" rel="noopener noreferrer"&gt;PR #740&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;ChatCraft already supported API key management for LLM providers like OpenAI, but there was a need to extend this functionality to other AI services. The primary goals were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Separate LLM providers from other AI services in the UI&lt;/li&gt;
&lt;li&gt;Implement API key management for Jina.ai&lt;/li&gt;
&lt;li&gt;Create a foundation for supporting additional document processing providers&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. UI Modifications
&lt;/h3&gt;

&lt;p&gt;First, I modified the settings dialog to clearly distinguish between different types of providers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changed "Providers" label to "LLM Providers"&lt;/li&gt;
&lt;li&gt;Added a new "Other AI Providers" section&lt;/li&gt;
&lt;li&gt;Implemented a consistent table layout matching the existing providers section&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Provider Architecture
&lt;/h3&gt;

&lt;p&gt;I created an abstraction for non-LLM providers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NonLLMProviders&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;apiUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Jina.ai Integration
&lt;/h3&gt;

&lt;p&gt;Implemented the JinaAIProvider class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JinaAIProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;NonLLMProviders&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JINA_AI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JINA_API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;fromSettings&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;JinaAIProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getSettings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nonLLMProviders&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jina AI&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// case 1 when the provider already exists in the settings&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;JinaAIProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// case 2 when the provider doesn't exist but the api key is set&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JinaAIProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// case 3 when the provider doesn't exist and the api key is not set&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JinaAIProvider&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provider Abstraction&lt;/strong&gt;: Initially, I created separate implementations for each provider type. However, after code review feedback, I realized there was a significant overlap with &lt;code&gt;ChatCraftProvider&lt;/code&gt;. This led to discussions about future refactoring to create a more generic provider system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;: Working with Jina.ai's API taught me the importance of graceful degradation. When users hit free-tier limits, we needed to provide clear guidance about API key usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document Processing Power&lt;/strong&gt;: During testing, I discovered Jina.ai's impressive capabilities - it successfully converted an 85-page PowerPoint PDF to markdown with high accuracy, opening possibilities for future document processing pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Challenges and Solutions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UI Consistency&lt;/strong&gt;: Initially, the new provider section had different sizing from the existing table. This was standardized after code review feedback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Organization&lt;/strong&gt;: The original implementation had some redundancy in provider management. This was resolved by better encapsulation and static utility functions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Better error handling for free-tier limitations&lt;/li&gt;
&lt;li&gt;Refactoring provider classes for better code reuse&lt;/li&gt;
&lt;li&gt;Support for additional document processing services&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This repository was too good to work on, in fact some of the knowledge that I have gained from here would be used in my own project &lt;a href="https://github.com/Kannav02/DialectMorph" rel="noopener noreferrer"&gt;DialectMorph&lt;/a&gt;, because both of the projects are utilising different AI clients but are encapsulating logic in a way which makes it easier to be integrated into any app&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>ai</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>Contributing to ORAssistant</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Sat, 23 Nov 2024 03:57:32 +0000</pubDate>
      <link>https://forem.com/kannav02/contributing-to-orassistant-22o2</link>
      <guid>https://forem.com/kannav02/contributing-to-orassistant-22o2</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I was pleased after having contributed to various repositories during Hacktoberfest, but as soon as Hacktoberfest, I had this new profound excitement to contribute to more Open-Sourced Projects. I had contributed to a lot of projects that had a tech stack that included both backend and fronted, but this time around I wanted to contribute to an AI-based project, particularly something related to RAG (Retrieval Augmented Generation) as I wanted to delve into it&lt;/p&gt;

&lt;h1&gt;
  
  
  ORAssistant
&lt;/h1&gt;

&lt;p&gt;While looking for a lot of repos based on RAG, I stumbled across a perfect open-sourced RAG tool, &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant" rel="noopener noreferrer"&gt;ORAssistant&lt;/a&gt;, which is again, a chatbot that responds to common questions or inquiries for a larger project.&lt;/p&gt;

&lt;p&gt;The architecture of this tool is quite complex, I am still trying to figure out how the main query architecture operates, but this is the exciting part, learning as I contribute.&lt;/p&gt;

&lt;h1&gt;
  
  
  Issue
&lt;/h1&gt;

&lt;p&gt;For my &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant/issues/75" rel="noopener noreferrer"&gt;first issue&lt;/a&gt;, I picked up one of the issues where the task was to automate the feedback loop, in Leyman terms, what this entails is that an RAG app usually depends on feedback from the user to further fine-tune the response, the task was to get this feedback from the user and store it in a database and feed it back to the model itself&lt;/p&gt;

&lt;p&gt;The architecture would look something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3x61e54a08qi0fk0z9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3x61e54a08qi0fk0z9l.png" alt="Image description" width="752" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently, the system stores the feedback in Google Sheets, which again is not an optimized approach&lt;/p&gt;

&lt;p&gt;This issue in itself would take around 4-5 PRs to get solved, but for the focus of this blog, I will restrict it to the first PR I have made.&lt;/p&gt;

&lt;h1&gt;
  
  
  First Pull Request
&lt;/h1&gt;

&lt;p&gt;For the first pull request, as evident from the discussions from the &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant/issues/75" rel="noopener noreferrer"&gt;issue&lt;/a&gt;, my task was to first get the database design set up and running. In doing so, I encountered a lot of issues&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues faced
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;During the setup, the documentation to get the &lt;code&gt;GOOGLE_SERVICE_KEY&lt;/code&gt; wasn't straightforward, so I had to double-check it with the maintainer and tweak a lot of settings in my personal Google account to get it up and running, the maintainers were helpful during the entire process&lt;/li&gt;
&lt;li&gt;There were some inconsistencies in the backend which led to the frontend not operating correctly, but one of the good things about this project is since the backend is changing dynamically, they have a mock backend so that while the backend is being developed, the fronted doesn't suffer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Main solution
&lt;/h2&gt;

&lt;p&gt;The solution that I had proposed for this &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant/pull/101" rel="noopener noreferrer"&gt;PR&lt;/a&gt;, revolved around the discussion of choosing the right database, after an elaborate discussion with the maintainer, we decided that it was best to use MongoDB for the project, thinking about scalability and flexibility in the fields due to the schema-less nature of MongoDB.&lt;/p&gt;

&lt;p&gt;After making the initial design, I opened a &lt;a href="https://github.com/The-OpenROAD-Project/ORAssistant/pull/101" rel="noopener noreferrer"&gt;PR&lt;/a&gt;, which was related to having the initial design setup for the frontend&lt;/p&gt;

&lt;p&gt;One of the issues faced during the process of getting this merged was that it wasn't passing a test in the CI pipeline, which wasn't related to an error in my code, but because some repository secrets were not being propagated to the fork of the repository that I was working on, so the maintainer had to give me &lt;code&gt;write&lt;/code&gt; access to the repo to get my PR merged&lt;/p&gt;

&lt;h1&gt;
  
  
  Further Contributions
&lt;/h1&gt;

&lt;p&gt;This PR would now act as the base for further PRs that would eventually solve the entire issue. To be honest, this is one of the best projects I have worked on in a while, it is taking me about 6-7 PRs to just solve one issue, this shows how intricate and developed the project is.&lt;/p&gt;

&lt;p&gt;I am really enjoying how my Open-Source Journey is shaping out to be.&lt;/p&gt;

</description>
      <category>python</category>
      <category>rag</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Publishing my Tool</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Sat, 23 Nov 2024 02:54:56 +0000</pubDate>
      <link>https://forem.com/kannav02/publishing-my-tool-55kd</link>
      <guid>https://forem.com/kannav02/publishing-my-tool-55kd</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I wanted to share my experience of publishing the package to &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;. This blog post details the process, challenges, and lessons learned during the release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Package Registry
&lt;/h2&gt;

&lt;p&gt;For DialectMorph, I chose to publish on &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM (Node Package Manager)&lt;/a&gt; as our primary package registry. The decision was influenced by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NPM's widespread adoption in the JavaScript/TypeScript ecosystem&lt;/li&gt;
&lt;li&gt;Excellent integration with both Node.js and Bun&lt;/li&gt;
&lt;li&gt;Robust documentation and community support&lt;/li&gt;
&lt;li&gt;Built-in versioning and dependency management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Release Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Package Preparation
&lt;/h3&gt;

&lt;p&gt;First, I had to prepare the package for NPM publication. This involved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dialect-morph"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dialectMorph"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/index.js

}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical changes included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up the version correctly&lt;/li&gt;
&lt;li&gt;making sure that the binary was being made available to the user when downloaded as an independent package&lt;/li&gt;
&lt;li&gt;Ensuring all dependencies were correctly listed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Build Process Configuration
&lt;/h3&gt;

&lt;p&gt;I configured the build process using Bun:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added TypeScript compilation settings&lt;/li&gt;
&lt;li&gt;Set up the build script to create the &lt;code&gt;dist&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Ensured the binary was properly executable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Testing and Verification
&lt;/h3&gt;

&lt;p&gt;Before publication, I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ran local installation tests using &lt;code&gt;bun link&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verified the CLI worked globally&lt;/li&gt;
&lt;li&gt;Tested all supported language conversions&lt;/li&gt;
&lt;li&gt;Validated configuration file handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Issues Encountered
&lt;/h2&gt;

&lt;p&gt;Before going to the user testing phase, I wanted to install this globally on my machine to test but since I already have it on my machine, so I ran a docker instance of NodeJS to verify all of the installation instructions&lt;/p&gt;

&lt;p&gt;P.S The docker instance is really more useful than using a VM in these instances, if you want to set it up, you can use the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; node:latest /bin/bash 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will open up a bash terminal to an instance that has node installed locally&lt;/p&gt;

&lt;p&gt;when I installed this, what I found was the binary was not being included in the &lt;code&gt;dialectMorph&lt;/code&gt; package , which was bad, so I had to make fixes for the same and publish my package again.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Testing Insights
&lt;/h2&gt;

&lt;p&gt;One of my friends tested the total installation process out and the following was found from his experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Installation Confusion&lt;/strong&gt;: Users were unclear about the difference between global and local installation. This led to adding clearer installation instructions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; dialect-morph  &lt;span class="c"&gt;# for global installation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API Key Configuration&lt;/strong&gt;: Users struggled with setting up API keys. We added multiple configuration options:

&lt;ul&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;li&gt;TOML configuration file&lt;/li&gt;
&lt;li&gt;Command-line arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Current Installation and Usage
&lt;/h2&gt;

&lt;p&gt;DialectMorph can now be installed globally via NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; dialect-morph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dialectMorph ./path/to/file.py &lt;span class="nt"&gt;-l&lt;/span&gt; java  &lt;span class="c"&gt;# Convert Python to Java&lt;/span&gt;
dialectMorph ./path/to/file.cpp &lt;span class="nt"&gt;-l&lt;/span&gt; python  &lt;span class="c"&gt;# Convert C++ to Python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For configuration, users can either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;~/.dialectMorph.config.toml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Use command-line arguments&lt;/li&gt;
&lt;li&gt;Set environment variables&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Full documentation is available on my &lt;a href="https://github.com/Kannav02/DialectMorph" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This release process has been a valuable learning experience, highlighting the importance of thorough documentation, user testing, and flexible configuration options. The NPM ecosystem provides an excellent platform for distributing CLI tools, and my friend's feedback has been invaluable in improving DialectMorph.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>typescript</category>
      <category>git</category>
      <category>npm</category>
    </item>
    <item>
      <title>CI and Dev Containers</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Mon, 18 Nov 2024 04:58:55 +0000</pubDate>
      <link>https://forem.com/kannav02/ci-and-dev-containers-3c0e</link>
      <guid>https://forem.com/kannav02/ci-and-dev-containers-3c0e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;For this week of contribution, I planned to implement a CI pipeline that will automate all of the checks made to any of the changes pushed to my main branch directly or via a PR&lt;/p&gt;

&lt;p&gt;In addition to this, since my project is becoming bigger and is open-sourced, I believe more people are going to contribute to this, so I also added the option to have dev-containers for the ease-of-use of a developer and better dev experience.&lt;/p&gt;

&lt;p&gt;Again, all of this work is being done on my project, &lt;a href="https://github.com/Kannav02/DialectMorph" rel="noopener noreferrer"&gt;DialectMorph&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CI Pipeline
&lt;/h2&gt;

&lt;p&gt;There are a lot of tools that could help with making CI/CD pipelines, but for this project, I decided to go with &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Github Action&lt;/a&gt;, this was because I was already familiar with it and it would be a perfect fit for my project&lt;/p&gt;

&lt;p&gt;Github Actions work on YAML Scripts, these are nothing but configuration files, similar to how JSON is used to provide configuration settings. YAML is much preferred in the field of DevOps to make configuration easy and human-readable&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;For my project, I have used the following configuration setting&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Linting and Formatting
on:
  push:
    branches:
      - main
      - master
  pull_request:
    branches:
      - main
      - master
jobs:
  lint:
    name: Prettier and ESLint
    runs-on: ubuntu-latest
    steps:
      - name: Checks Out the Repository
        uses: actions/checkout@v4
      - name: Setup NodeJS
        uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Sets up the Bun enviornment
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: "latest"
      - name: Installing Bun Dependencies
        run: |
          bun install .
          bun install -D jest ts-jest @types/jest typescript
      - name: Linting The Code
        run: |
          bun eslint .
      - name: Checking for Formatting
        run: |
          bunx prettier . --check
      - name: Running Tests
        run: |
          npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the Github Actions config file, three things are necessary for a valid configuration which are &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: Informs the name of the script &lt;/li&gt;
&lt;li&gt;on: Event that triggers the CI/CD pipeline&lt;/li&gt;
&lt;li&gt;jobs: Tasks that would run when the event is triggered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My specific configuration is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push or Pull Requests to the Main Branch trigger the CI script&lt;/li&gt;
&lt;li&gt;Once the event is triggered, the first command sets up the environment to run on an  Ubuntu virtual machine&lt;/li&gt;
&lt;li&gt;Then the repository is cloned on the VM and &lt;code&gt;bun&lt;/code&gt; installs dependencies and runs the project&lt;/li&gt;
&lt;li&gt;The project is checked for any listing errors&lt;/li&gt;
&lt;li&gt;The project is then checked for consistent formatting based on the prettier rules that are in the project&lt;/li&gt;
&lt;li&gt;At last, the test-suite is run to check for any errors occurring during the changes that are coming from a different branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Github actions helped me automate all of the checks that I would have to do manually just to ensure no major errors were occurring in my codebase and no tech debt was being stacked on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev Containers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/devcontainers/containers" rel="noopener noreferrer"&gt;Dev-Containers&lt;/a&gt;, are one of the best tools for developers collaborating on a project and wanting to have a consistent platform to keep up with development, ignoring the dependency issues on each of their local machines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Env Setup
&lt;/h3&gt;

&lt;p&gt;To get this setup for my project, I had to provide the developer with the option to develop inside a container, which meant I had to configure the settings for my &lt;code&gt;dev-container&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;My project utilizes &lt;code&gt;bun&lt;/code&gt; as the main package-handler tool, and it is not that easy to set it up on different machines, so I had to provide a Dockerfile as the base for my dev-container&lt;/p&gt;

&lt;p&gt;for my Dockerfile, I utilized the following settings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM --platform=$TARGETPLATFORM ubuntu:latest

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y curl unzip git

RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this ran the container in an Ubuntu image, it installs git curl and  unzip as the machine dependencies, so that the user shouldn't have the issue of installing them manually&lt;/p&gt;

&lt;p&gt;then it sets up the &lt;code&gt;bun&lt;/code&gt; package manager on the container for &lt;/p&gt;

&lt;p&gt;now for the actual &lt;code&gt;dev-container.json&lt;/code&gt; configuration , I have used the following settings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name": "Dev Container For DialectMorph",
    "build": {
        "dockerfile": "Dockerfile"
    },
    "customizations": {
        "vscode": {
            "settings": {
                "window.zoomLevel": 0.5,
                "workbench.tree.indent": 20,
                "editor.minimap.renderCharacters": false,
                "files.autoSave": "afterDelay",
                "files.autoSaveDelay": 1000,
                "editor.cursorBlinking": "smooth",
                "files.eol": "\n",
                "files.trimTrailingWhitespace": true,

                "editor.defaultFormatter": "esbenp.prettier-vscode",
                "editor.formatOnSave": true,

                "prettier.trailingComma": "es5",
                "prettier.semi": true,
                "prettier.tabWidth": 2,
                "prettier.useTabs": true,
                "prettier.printWidth": 80,

                "editor.codeActionsOnSave": {
                    "source.fixAll.eslint": "always"
                },
                "eslint.validate": ["typescript"]
            },
            "extensions": [
                "dbaeumer.vscode-eslint", // ESLint support
                "esbenp.prettier-vscode", // Prettier formatting
                "ms-vscode.vscode-typescript-next", // TypeScript support
                "aaron-bond.better-comments", // Better code comments
                "christian-kohler.path-intellisense", // Path autocompletion
                "streetsidesoftware.code-spell-checker", // Spell checking
                "eamodio.gitlens", // Git integration
                "yoavbls.pretty-ts-errors", // Better TypeScript errors
                "wayou.vscode-todo-highlight", // Highlight TODOs
                "gruntfuggly.todo-tree" // Track TODOs
            ]
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in this, I have provided the base of my dev-container to be the Dockerfile and then added the recommended vs code setting and extensions which would help the user in the development&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I successfully implemented a CI pipeline using GitHub Actions for my DialectMorph project, automating all the necessary code checks and testing processes. As my project grows, I wanted to ensure quality and consistency, which led me to configure the pipeline to run on both direct pushes and pull requests to the main branch. To make it even more contributor-friendly, I added dev container support with custom VS Code configurations, making it significantly easier for other developers to jump in and start contributing without worrying about environment setup&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>github</category>
      <category>opensource</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Testing with Jest</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Mon, 11 Nov 2024 03:23:16 +0000</pubDate>
      <link>https://forem.com/kannav02/testing-with-jest-18gm</link>
      <guid>https://forem.com/kannav02/testing-with-jest-18gm</guid>
      <description>&lt;h1&gt;
  
  
  A Guide to Testing in TypeScript Projects: Overcoming Challenges with Jest and Bun
&lt;/h1&gt;

&lt;p&gt;In this blog post, I’ll walk you through my experience setting up and using &lt;strong&gt;Jest&lt;/strong&gt; for testing in a TypeScript project. Along the way, I’ll share the hurdles I faced, particularly when trying to use Jest with Bun (my preferred package manager), and how I handled mocking LLM (Large Language Model) responses.&lt;/p&gt;

&lt;p&gt;Again I will be demoing this on my project, &lt;a href="https://github.com/Kannav02/DialectMorph" rel="noopener noreferrer"&gt;DialectMorph&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Jest
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Framework
&lt;/h3&gt;

&lt;p&gt;When it comes to testing, &lt;strong&gt;Jest&lt;/strong&gt; is one of the most popular frameworks for JavaScript and TypeScript projects. I chose Jest because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Setup:&lt;/strong&gt; Jest works out of the box with minimal configuration for most projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Mocks and Spies:&lt;/strong&gt; Jest has built-in support for mocking and spying, which makes it easy to isolate parts of your code, especially when working with external dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot Testing:&lt;/strong&gt; Jest provides the ability to perform snapshot testing, useful when dealing with complex objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Ecosystem and Community:&lt;/strong&gt; With a large community and lots of plugins, Jest offers solid support and continuous improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information, you can visit Jest’s official documentation: &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bun: The Package Manager
&lt;/h3&gt;

&lt;p&gt;I use &lt;strong&gt;Bun&lt;/strong&gt; as my package manager for managing dependencies in my TypeScript projects. It is known for its speed and simplicity. However, I encountered a significant issue with Bun and Jest compatibility that I’ll elaborate on later. You can learn more about Bun at &lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;Bun&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initial Setup
&lt;/h3&gt;

&lt;p&gt;To get started, I first installed &lt;strong&gt;Jest&lt;/strong&gt;, &lt;strong&gt;TypeScript&lt;/strong&gt;, and related dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun add &lt;span class="nt"&gt;-d&lt;/span&gt; jest ts-jest @types/jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Bun to the Mix
&lt;/h3&gt;

&lt;p&gt;Since I use &lt;strong&gt;Bun&lt;/strong&gt; as my package manager, I ran into issues while trying to use Bun with Jest, as Bun doesn't natively support Jest out-of-the-box. This led to several frustrating days of trying to resolve compatibility problems. After many attempts at using &lt;code&gt;bun test&lt;/code&gt; for Jest, I eventually had to work around it by running Jest directly using &lt;code&gt;npm&lt;/code&gt;(even though Bun was the default package manager).&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;Bun for dependency management&lt;/strong&gt; and &lt;strong&gt;npm for testing&lt;/strong&gt;. This workaround helped resolve the Jest compatibility issue but resulted in additional setup time and confusion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install
&lt;/span&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mocking LLM Responses
&lt;/h3&gt;

&lt;p&gt;One of the key challenges in testing is handling external dependencies, especially when dealing with large language models (LLMs) or API calls. In my project, I needed mock responses from LLMs interacting with the file system.&lt;/p&gt;

&lt;p&gt;To achieve this, I used Jest’s powerful mocking abilities. I mocked several modules (&lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;os&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, and &lt;code&gt;toml&lt;/code&gt;) to isolate the functions under test. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows me to simulate different scenarios without actually interacting with the file system or external dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Test Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  File Utility Functions
&lt;/h3&gt;

&lt;p&gt;I had a set of utility functions to test, including file operations like creating directories and files. Here's how I structured the test cases for one of the functions, &lt;code&gt;makeDir&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;makeDir Function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Creates a Directory and returns its path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;testDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mkdirSync&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root/testDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root/testDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doesn't create directory if it already exists&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;existsSync&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;testDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root/testDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mkdirSync&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of the utility functions (&lt;code&gt;makeDir&lt;/code&gt;, &lt;code&gt;createFile&lt;/code&gt;, &lt;code&gt;extractCodeBlock&lt;/code&gt;, &lt;code&gt;loadTomlConfigFile&lt;/code&gt;) had corresponding test cases that mocked the necessary parts of the code (like file reading and writing) to avoid side effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Learned from Writing Test Cases
&lt;/h3&gt;

&lt;p&gt;Writing test cases helped me discover several interesting things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mocking complexity:&lt;/strong&gt; Mocking certain modules, especially system-level ones like &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;os&lt;/code&gt;, and &lt;code&gt;path&lt;/code&gt;, proved tricky. However, Jest’s &lt;code&gt;jest.mock&lt;/code&gt; function made this easier once I figured out how to properly mock these external dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mocking non-trivial dependencies:&lt;/strong&gt; One of the most challenging parts of mocking was the &lt;code&gt;toml&lt;/code&gt; parsing, as it involved simulating both file reading and parsing logic. But with proper mocks, I could easily simulate various file contents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test organization:&lt;/strong&gt; I found that grouping related tests together (as seen in the nested &lt;code&gt;describe&lt;/code&gt; blocks) kept my tests organized and made them easier to read and maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jest and Bun compatibility issues:&lt;/strong&gt; The biggest obstacle I encountered was integrating Jest with Bun. This issue caused a lot of wasted time, and I had to use &lt;strong&gt;npm&lt;/strong&gt; instead of &lt;strong&gt;Bun&lt;/strong&gt; for running tests. This was a frustrating experience and a learning moment about the importance of checking compatibility early in the process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mocking non-obvious behaviors:&lt;/strong&gt; Another moment of realization was learning how to mock file system behaviors, especially with Jest's ability to mock implementation details like file reads and writes. This was crucial to avoid side effects in tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Uncovered Bugs and Edge Cases
&lt;/h3&gt;

&lt;p&gt;While writing tests, I discovered some edge cases in the file utility functions. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Handling non-existent files:&lt;/strong&gt; There were scenarios where the code didn't handle the absence of files correctly. By testing this behavior, I was able to ensure that the code didn’t break and returned expected results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unexpected behaviors with path resolution:&lt;/strong&gt; By mocking the &lt;code&gt;path&lt;/code&gt; module, I ensured that the directory and file paths were correctly resolved across different environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This process has been an eye-opener in terms of testing and mocking in JavaScript/TypeScript. Prior to this project, I hadn’t done much testing, and it was rewarding to see how structured testing could catch bugs and ensure code correctness.&lt;/p&gt;

&lt;p&gt;I believe personally, I would rather avoid writing test cases at least after most of the code is written as it gets too complicated, for me If I know I have to write tests, I would rather begin with a TDD approach&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Local Dev Environment and Static Code Analysis</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Fri, 01 Nov 2024 18:58:23 +0000</pubDate>
      <link>https://forem.com/kannav02/local-dev-environment-and-static-code-analysis-1pda</link>
      <guid>https://forem.com/kannav02/local-dev-environment-and-static-code-analysis-1pda</guid>
      <description>&lt;p&gt;For this week, I decided to improve the developer-friendliness nature of my project, &lt;a href="https://github.com/Kannav02/DialectMorph" rel="noopener noreferrer"&gt;DialectMorph&lt;/a&gt;. I took on the responsibility to automate the various setup procedures that a developer needs to get the project running locally on their machine,I will now elaborate the use-case of each of them in this blog&lt;/p&gt;

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

&lt;p&gt;Given that my codebase is open-sourced, a lot of developers might contribute to it. This sometimes leads to the having inconsistent code-formatting, which might not be a good thing when it comes to providing a clean and smooth developer experience&lt;/p&gt;

&lt;p&gt;So for this, I utilized &lt;a href="https://prettier.io/docs/en/editors" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;, which is a library used to support the task of formatting &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;This tool is used to specify the formatting options which would remain consistent throughout the codebase,&lt;br&gt;
All of the configuration settings for the same go into a config file called &lt;code&gt;.prettierrc&lt;/code&gt; or any other supported file formats the tool provides which can be found in the documentation.&lt;/p&gt;

&lt;p&gt;For my codebase, I have applied the following settings which would be tailored to my project&lt;/p&gt;

&lt;p&gt;File-Name: &lt;code&gt;.prettierrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "trailingComma": "es5",
    "semi": true,
    "tabWidth": 2,
    "printWidth": 80,
    "useTabs": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the options here provide me with the following functionality &lt;br&gt;
having trailing commas whenever it is included near the es5 syntax&lt;br&gt;
semicolons at the end of every statement&lt;br&gt;
Sets the number of spaces per indentation level to 2 &lt;br&gt;
Limits line length to 80 characters.&lt;br&gt;
It uses tabs for indentation instead of spaces&lt;/p&gt;

&lt;p&gt;Now I would also want to ignore certain files or certain code blocks to not be formatted, for that use-case I have two options that is&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using a file called &lt;code&gt;.prettierignore&lt;/code&gt; to include all the files that I want to ignore&lt;/li&gt;
&lt;li&gt;I can also place the statement called &lt;code&gt;prettier-ignore&lt;/code&gt; before the code blocks I don't want to be formatted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My initial formatting with prettier changed about &lt;code&gt;500&lt;/code&gt; lines in my codebase&lt;/p&gt;

&lt;p&gt;I have configured the following scripts in my &lt;code&gt;package.json&lt;/code&gt; to have ease-of-use to call this tool&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;        &lt;span class="s2"&gt;"format"&lt;/span&gt;: &lt;span class="s2"&gt;"bunx prettier . --write"&lt;/span&gt;,
        &lt;span class="s2"&gt;"format:check"&lt;/span&gt;: &lt;span class="s2"&gt;"bunx prettier . --check"&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Linting
&lt;/h2&gt;

&lt;p&gt;Linting is one of the common practices used in codebases to ensure the code is more consistent and to identify patterns that could lead to potential bugs&lt;/p&gt;

&lt;p&gt;For my project, I utilized the tool called &lt;a href="https://eslint.org/docs/latest/use/getting-started" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt; since it is compatible with typescript based projects&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;I used this tool to make sure that there was no errors or unused variables in my projects, also I had a couple of configuration settings as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import globals from "globals";
import tseslint from "@typescript-eslint/eslint-plugin";
import tseslintParser from "@typescript-eslint/parser";

export default [
    {
        files: ["**/*.{js,mjs,cjs,ts}"],
        languageOptions: {
            globals: {
                ...globals.browser,
            },
            parser: tseslintParser,
            parserOptions: {
                ecmaVersion: "latest",
                sourceType: "module",
            },
        },
        plugins: {
            "@typescript-eslint": tseslint,
        },
        rules: {
            ...tseslint.configs.recommended.rules,
        },
    },
    {
        files: ["dist/**/*.js"],
        rules: {
            "@typescript-eslint/no-unused-expressions": "off",
            "@typescript-eslint/no-require-imports": "off",
        },
    },
    {
        files: ["examples/**/*.js"],
        rules: {
            "@typescript-eslint/no-unused-expressions": "off",
            "@typescript-eslint/no-require-imports": "off",
            "@typescript-eslint/no-unused-vars": "off",
        },
    },
    {
        files: ["src/index.ts"],
        rules: {
            "@typescript-eslint/no-explicit-any": "off",
        },
    },
];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration file manages linting rules for my project through multiple configuration blocks. The primary block sets up basic TypeScript linting for all code files with browser globals and recommended rules, while subsequent blocks relax specific rules for distribution files and examples. Finally, it includes a special configuration for src/index.ts that allows the use of the any type.&lt;/p&gt;

&lt;p&gt;I have configured the following scripts in my &lt;code&gt;package.json&lt;/code&gt; to have ease-of-use to call this tool&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"lint"&lt;/span&gt;: &lt;span class="s2"&gt;"bun eslint ."&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Local Dev Environment
&lt;/h2&gt;

&lt;p&gt;I wanted to make sure that the developer that is working on my repository has a smooth experience while setting up my repository.&lt;/p&gt;

&lt;p&gt;I have been working on my codebase in VSCode mostly, so I decided to include a &lt;code&gt;.vscode&lt;/code&gt; folder which would allow me to specify the necessary things needed for a smooth experience&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;extensions.json&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;This file contains the name of all the extensions that would provide a better experience to the developer while they are working on my repository, when the users open ups my repository for the first time, &lt;br&gt;
they will see the prompt to install the recommended extensions, for my program you can see the recommended extensions as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "recommendations": [
        "dbaeumer.vscode-eslint", // ESLint support
        "esbenp.prettier-vscode", // Prettier formatting
        "ms-vscode.vscode-typescript-next", // TypeScript support
        "aaron-bond.better-comments", // Better code comments
        "christian-kohler.path-intellisense", // Path autocompletion
        "streetsidesoftware.code-spell-checker", // Spell checking
        "eamodio.gitlens", // Git integration
        "yoavbls.pretty-ts-errors", // Better TypeScript errors
        "wayou.vscode-todo-highlight", // Highlight TODOs
        "gruntfuggly.todo-tree" // Track TODOs
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;settings.json&lt;/code&gt;file
&lt;/h3&gt;

&lt;p&gt;The file contains all the editor settings for VSCode, that again is not necessarily needed but is again used for a great and seamless experience for the developer. I believe if you want people to work on your codebase, automate the manual setup things and provide them with a great experience.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;settings.json&lt;/code&gt; file is particularly used for specifying the setting for VSCode editor and environment&lt;/p&gt;

&lt;p&gt;I have provided the following settings for the same&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// arbitary settings for vs code to have good config settings

{
    "window.zoomLevel": 0.5,
    "workbench.tree.indent": 20,
    "editor.minimap.renderCharacters": false,
    "files.autoSave": "afterDelay",
    "files.autoSaveDelay": 1000,
    "editor.cursorBlinking": "smooth",
    "files.eol": "\n",
    "files.trimTrailingWhitespace": true,

    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,

    "prettier.trailingComma": "es5",
    "prettier.semi": true,
    "prettier.tabWidth": 2,
    "prettier.useTabs": true,
    "prettier.printWidth": 80,

    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": "always"
    },
    "eslint.validate": ["typescript"]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git Hooks (Pre-Commit)
&lt;/h2&gt;

&lt;p&gt;Git-Hooks are scripts that automatically run at a specified timeline in the git execution pipeline, they are triggered at different events like having a &lt;code&gt;pre-commit&lt;/code&gt; hook, a &lt;code&gt;post-commit&lt;/code&gt; hook. They are really useful to perform additional sanity testing task or basic cleaning tasks before the data is pushed or committed&lt;/p&gt;

&lt;p&gt;For my use-case I have only utilised &lt;code&gt;pre-commit&lt;/code&gt; hook as I didn't see the use of having other hooks right now in my project&lt;/p&gt;

&lt;p&gt;To implement these hooks I have utilised another library called &lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;&lt;code&gt;husky&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How this works is you can specify the type of git events you want and what command should run when the git event occurs,for my package.json I have the following settings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    &lt;span class="s2"&gt;"husky"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"hooks"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"pre-commit"&lt;/span&gt;: &lt;span class="s2"&gt;"bun run format"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the above command specifies that there is only a pre-commit event that would run the command to format my entire code before committing it.&lt;/p&gt;

&lt;p&gt;This is by far one of the best things I have come across recently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Through the implementation of tools like Prettier, ESLint, VSCode configurations, and Git hooks, I've significantly reduced the manual setup burden for potential contributors. These improvements not only make the codebase more maintainable but also create a welcoming environment for developers who might want to contribute to the project in the future.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>github</category>
    </item>
    <item>
      <title>My Fourth and Final Contribution to Hacktoberfest</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Mon, 28 Oct 2024 02:36:49 +0000</pubDate>
      <link>https://forem.com/kannav02/my-fourth-and-final-contribution-to-hacktoberfest-1g8d</link>
      <guid>https://forem.com/kannav02/my-fourth-and-final-contribution-to-hacktoberfest-1g8d</guid>
      <description>&lt;p&gt;My 4th and final contribution to Hacktoberfest was made to a repository that I have contributed to in the past, &lt;a href="https://github.com/DiceDB/dice" rel="noopener noreferrer"&gt;DiceDB&lt;/a&gt;. The project is centered around the idea of being an in-drop replacement of Redis while being more optimized than it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Issue
&lt;/h2&gt;

&lt;p&gt;Previously I had contributed to this repository by solving an issue that was related to testing out a particular Database Operation ensuring the functionality aligns with the documentation and if needed making changes to the documentation.&lt;/p&gt;

&lt;p&gt;This time around, I wanted to contribute to the codebase, part of the reason being I wanted to learn &lt;code&gt;GoLang&lt;/code&gt; and the other being getting a gist of how tools/software like &lt;code&gt;DiceDB&lt;/code&gt; are built, what is the intuition to such a good design.&lt;/p&gt;

&lt;p&gt;So I found an issue that was not too hard to grasp initially but would also help me achieve the goals I mentioned earlier.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/DiceDB/dice/issues/1103" rel="noopener noreferrer"&gt;issue&lt;/a&gt; was centered around the idea of resolving and fixing a certain error message and giving the right error message in an appropriate situations&lt;/p&gt;

&lt;h2&gt;
  
  
  Process of finding and correcting the error
&lt;/h2&gt;

&lt;p&gt;The idea was to first find the issue and then resolve it&lt;/p&gt;

&lt;p&gt;Since I had pretty much no knowledge of how &lt;code&gt;GoLang&lt;/code&gt; works, I first went to the docs for the same, familiarized myself with the first principles and the syntax of &lt;code&gt;GoLang&lt;/code&gt;, and then went back to solve the issue&lt;/p&gt;

&lt;p&gt;Since this project was vast, I utilized VSCode's search functionality to find where the error was being logged, and what functions were associated with the error message.&lt;/p&gt;

&lt;p&gt;After I found the Point-of-Interests for me, what I did was to isolate the issue from the other parts of the codebase, made the current logic make sense to me, separate the error message, and then add the fixes for the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR
&lt;/h2&gt;

&lt;p&gt;After I had resolved the issue, I opened a &lt;a href="https://github.com/DiceDB/dice/pull/1170" rel="noopener noreferrer"&gt;PR&lt;/a&gt; to get my changes approved and merged into the main branch, but turns out someone else had there changes merged into the main, so there was conflicts&lt;/p&gt;

&lt;p&gt;I then had to use the &lt;code&gt;rebase&lt;/code&gt; command to rebase my topic-branch on top of the new changes that were merged into &lt;code&gt;main&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
git rebase main 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After doing so, there were no conflicts and soon the PR was approved by the maintainer to be merged into the repo &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion To Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;In wrapping up my Hacktoberfest contributions, working on DiceDB allowed me to dive deeper into Go and learn firsthand how a Redis alternative is built. Resolving an error-handling issue helped me grasp Go’s syntax and debugging in a real-world codebase.&lt;/p&gt;

&lt;p&gt;This entire experience shaped how the dilemma that I used to have with contributing to OSS projects, it gave me one of the best skills that any developer could have i.e. adaptability as during my experience with Hacktoberfest, Almost all of my contributions have been to projects that have used a tech-stack that I've never had any experience with &lt;/p&gt;

&lt;p&gt;I have loved each and every aspect of Hacktoberfest!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>go</category>
      <category>redis</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Hacktoberfest contribution to ZTM-Quest</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Wed, 23 Oct 2024 04:03:39 +0000</pubDate>
      <link>https://forem.com/kannav02/hacktoberfest-contribution-to-ztm-quest-d38</link>
      <guid>https://forem.com/kannav02/hacktoberfest-contribution-to-ztm-quest-d38</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;For my third contribution to Hacktoberfest, I found a repository that I never thought would be the one that I would contribute to, this repository was particularly centered around 2D-Game Dev in JavaScript since I already had a working knowledge of JavaScript, diving and exploring the codebase wouldn't have been a problem so I picked up one of the issues in this repository to contribute to.&lt;/p&gt;

&lt;h2&gt;
  
  
  ZTM-Quest
&lt;/h2&gt;

&lt;p&gt;The repository was named &lt;a href="https://github.com/zero-to-mastery/ZTM-Quest" rel="noopener noreferrer"&gt;ZTM-Quest&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/zero-to-mastery/ZTM-Quest/issues/21" rel="noopener noreferrer"&gt;issue&lt;/a&gt; that I picked up to solve was related to adding a &lt;code&gt;end-credits&lt;/code&gt; scene to the game which would dynamically fetch the name of the contributors from the Github API and would also fetch the asset credits as well and display them in a scrolling manner, something similar to how normal 2D games would do nowadays.&lt;/p&gt;

&lt;p&gt;Further features which were to be included were &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a button to trigger the credits scene and to exit the scene&lt;/li&gt;
&lt;li&gt;Providing the options via the keyboard to exit/trigger the credits scene &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  KAPLAY
&lt;/h2&gt;

&lt;p&gt;The entire program used the &lt;code&gt;KAPLAY&lt;/code&gt; framework, which is a framework that can be used in Javascript to make 2D games&lt;/p&gt;

&lt;p&gt;The whole abstract idea behind this is to have various components or characters that can interact with each other to trigger interactions. The background image that a developer could provide in the program is known as a &lt;code&gt;sprite&lt;/code&gt; here, it could even be a map where the character or the components could be placed and can lead to different interactions&lt;/p&gt;

&lt;p&gt;What I found was most of 2D-Game Dev involved manipulating objects geometrically in a 2D plane with the added features of interaction and dynamic resizing &lt;/p&gt;

&lt;h2&gt;
  
  
  Core Changes Made
&lt;/h2&gt;

&lt;p&gt;The core changes that I made over here were as follows&lt;/p&gt;

&lt;h3&gt;
  
  
  Intuition
&lt;/h3&gt;

&lt;p&gt;The intuition that followed this was that the program would have 3 components, a background, a text container or text itself, and an exit button&lt;/p&gt;

&lt;p&gt;My first iteration of changes involved making those but later on I realized it would be better to have a &lt;code&gt;sprite&lt;/code&gt; in the background as well, so I made the following changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const background = k.add([
        k.sprite("backgroundImage", { width: k.width(), height: k.height() }),
        k.pos(0, 0),
        k.opacity(0.2),
        k.scale(1),
        k.z(60),
        k.fixed()
    ]);


    const overlay = k.add([
        k.rect(k.width(), k.height()),
        k.pos(0, 0),
        k.color(0, 0, 0),  // 40% transparent black
        k.z(50),  
        k.fixed()
    ]);

    // Add the credit text
    const center = k.vec2((k.canvas.width / 2), k.canvas.height / 2);
    const text = k.add([
        k.text(creditText, {
            size: 15 / camScale,
            width: k.width() * 0.9 / camScale,
            lineSpacing: 15 / camScale,
            align: "center"
        }),
        k.pos(k.width() / 2, k.height()),
        k.anchor("top"),
        k.color(255, 255, 255),
        k.z(101),
        k.scale(camScale)
    ]);

    const crossButton = k.add([
        k.rect(65, 35),
        k.color(255, 0, 0),
        k.anchor('topright'),
        k.z(101),
        k.area(),
        k.scale(1),
    ]);

    const exitText = k.add([
        k.text("Exit", { size: 26 / camScale }),
        k.color(255, 255, 255),
        k.anchor("topright"),
        k.z(102),
        k.scale(camScale)
    ]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as can be seen, I put an overlay as well to make the image be less in focus than the text itself&lt;/p&gt;

&lt;p&gt;as for the text that is to be displayed I made two functions that would fetch the data for me, which then I could put in the &lt;code&gt;creditText&lt;/code&gt; field&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getAssets(){
    const fileSHA = await fetch("https://api.github.com/repos/zero-to-mastery/ZTM-Quest/contents/asset_credits.md")
    const data = await fileSHA.json()
    const fileContents = atob(data.content)
    return fileContents.split("\n").filter(content=&amp;gt;content.trim()!=='').join("\n")
}

export async function getContributors(){
    const contributors = await fetch("https://api.github.com/repos/zero-to-mastery/ZTM-Quest/contributors")
    const data = await contributors.json()
    return data.map((person)=&amp;gt;{
        return person.login
    }).join("\n")

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believe that whenever an API is being requested for the data, 90% of the task is to transform the data so that the developer can utilize it optimally, that's what I did here.  &lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience With the Repo
&lt;/h2&gt;

&lt;p&gt;To be honest, this is one of the most interesting issues I have worked on before I never knew how to work with 2D-GameDev frameworks in JavaScript, this gave me the much-needed experience, and I enjoyed contributing to this&lt;/p&gt;

&lt;p&gt;In fact one of the other things that I have learned while contributing to this was the proper usage of &lt;code&gt;git rebase&lt;/code&gt; and &lt;code&gt;git checkout -B&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;These commands literally saved the day for me,&lt;/p&gt;

&lt;p&gt;I utilized &lt;code&gt;git rebase&lt;/code&gt; frequently to make my issue branch in sync with the changes being merged into the &lt;code&gt;main&lt;/code&gt; branch upstream and to avoid conflicts as well&lt;/p&gt;

&lt;p&gt;I utilized &lt;code&gt;git checkout -B&lt;/code&gt; when I used to mess up the code on the branch and wanted to go back to the latest working commit&lt;/p&gt;

&lt;p&gt;I usually used to do the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
git checkout &lt;span class="nt"&gt;-B&lt;/span&gt; issue-branch latest-working-commit

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is my 3rd Hacktoberfest contribution and I am loving contributing to Open-Source, the amount of hands-on experience I have gained this time around is unbeatable&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>hacktoberfest</category>
      <category>github</category>
      <category>javascript</category>
    </item>
    <item>
      <title>My Hacktoberfest Contribution To DiceDB</title>
      <dc:creator>Kannav Sethi</dc:creator>
      <pubDate>Thu, 10 Oct 2024 19:40:33 +0000</pubDate>
      <link>https://forem.com/kannav02/my-hacktobefest-contribution-to-dicedb-4egg</link>
      <guid>https://forem.com/kannav02/my-hacktobefest-contribution-to-dicedb-4egg</guid>
      <description>&lt;p&gt;This week I had the opportunity to work on &lt;a href="https://github.com/DiceDB/dice" rel="noopener noreferrer"&gt;DiceDB&lt;/a&gt; which is a drop-in replacement of &lt;code&gt;Redis&lt;/code&gt; and is much faster than it as well&lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;Redis&lt;/code&gt; is an open-source in-memory database, that can be used for the purpose of storing data, caching, or as a message broker&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DiceDB&lt;/code&gt; improves on the benchmarks and also differs in two aspects from &lt;code&gt;Redis&lt;/code&gt; i.e.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is multi-threaded&lt;/li&gt;
&lt;li&gt;Listens to SQL query and informs the client about the changes as soon as possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  My Contribution
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Issue
&lt;/h2&gt;

&lt;p&gt;I saw an issue that was related to auditing the documentation concerning the &lt;code&gt;PFMERGE&lt;/code&gt; command&lt;/p&gt;

&lt;p&gt;To briefly describe what the issue was :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The documentation for the &lt;code&gt;PFMERGE&lt;/code&gt; command might have become stale, audit and fix it&lt;/li&gt;
&lt;li&gt;As the tool is a drop-in replacement of &lt;code&gt;Redis&lt;/code&gt;, check if the functionality of the command matches the functionality mentioned in the &lt;code&gt;Redis&lt;/code&gt; documentation &lt;/li&gt;
&lt;li&gt;Make the documentation for the command consistent with the new proposed format that is to make appropriate use of headers, add terminal examples and use proper table format for arguments and error output types&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Approach
&lt;/h2&gt;

&lt;p&gt;I've been wanting to learn &lt;code&gt;Redis&lt;/code&gt; for a while, but have never taken the time to do so, this issue helped me learn more about how &lt;code&gt;Redis&lt;/code&gt; operates and how &lt;code&gt;DiceDB&lt;/code&gt; is different from it&lt;/p&gt;

&lt;p&gt;To get myself acquainted with the technology, I went to the official documentation page of &lt;a href="https://redis.io/docs/latest/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt;, read through the documentation, different data types, and quickstart guide, and then ran a Docker container for the same on my local machine to experiment with it&lt;/p&gt;

&lt;p&gt;After I was done exploring &lt;code&gt;Redis&lt;/code&gt;, I moved on to get &lt;code&gt;DiceDB&lt;/code&gt; working on my machine, most of the commands that I ran in &lt;code&gt;DiceDB&lt;/code&gt; ran through the help of &lt;code&gt;redis-cli&lt;/code&gt; tool, which allowed me to connect to the Docker instance of &lt;code&gt;DiceDB&lt;/code&gt; running on my machine&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;PFMERGE&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;I was acquainted with common data types like, &lt;code&gt;JSON&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Sets&lt;/code&gt; and &lt;code&gt;Lists&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But this time around I came across a new Data Type, known as &lt;a href="https://redis.io/docs/latest/develop/data-types/probabilistic/hyperloglogs/" rel="noopener noreferrer"&gt;HyperLogLog&lt;/a&gt;, which estimates the cardinality of the elements in its set, this was a type of a probabilistic data structure&lt;/p&gt;

&lt;p&gt;Any command that started with a &lt;code&gt;PF&lt;/code&gt; probably dealt with the use of HyperLogLog Data structure, my task at hand was to see how &lt;code&gt;PFMERGE&lt;/code&gt; was performing and how is it giving outputs and handling error&lt;/p&gt;

&lt;p&gt;Some of the examples I ran here were&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;127.0.0.1:7379&amp;gt; PFADD hll1 &lt;span class="s2"&gt;"a"&lt;/span&gt; &lt;span class="s2"&gt;"b"&lt;/span&gt; &lt;span class="s2"&gt;"c"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 1
127.0.0.1:7379&amp;gt; PFADD hll2 &lt;span class="s2"&gt;"c"&lt;/span&gt; &lt;span class="s2"&gt;"d"&lt;/span&gt; &lt;span class="s2"&gt;"e"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 1
127.0.0.1:7379&amp;gt; PFADD hll3 &lt;span class="s2"&gt;"e"&lt;/span&gt; &lt;span class="s2"&gt;"f"&lt;/span&gt; &lt;span class="s2"&gt;"g"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 1
127.0.0.1:7379&amp;gt; PFMERGE hll_merged hll1 hll2 hll3
OK
127.0.0.1:7379&amp;gt; PFCOUNT hll_merged
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;127.0.0.1:7379&amp;gt; PFADD hll_merged &lt;span class="s2"&gt;"x"&lt;/span&gt; &lt;span class="s2"&gt;"y"&lt;/span&gt; &lt;span class="s2"&gt;"z"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 1
127.0.0.1:7379&amp;gt; PFMERGE hll_merged hll1 hll2 hll3
OK
127.0.0.1:7379&amp;gt; PFCOUNT hll_merged
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;127.0.0.1:7379&amp;gt; PFMERGE hll_merged hll1 hll2 non_existent_key
OK
127.0.0.1:7379&amp;gt; PFCOUNT hll_merged
&lt;span class="o"&gt;(&lt;/span&gt;integer&lt;span class="o"&gt;)&lt;/span&gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;all of these examples gave me an overview of how this command worked&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Changes
&lt;/h2&gt;

&lt;p&gt;Once I was done with all of the pre-requisite stuff, I finally went on to audit the documentation and my changes were as follows &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changed the terminal to reflect the correct port number being used to access the docker instance&lt;/li&gt;
&lt;li&gt;Added another example, in the example usage section demonstrating invalid usage of the command&lt;/li&gt;
&lt;li&gt;Converted the formatting of the &lt;code&gt;Return Values&lt;/code&gt; and &lt;code&gt;Parameters&lt;/code&gt; sections to a table format&lt;/li&gt;
&lt;li&gt;Modified the expected behavior to match the functionality of how the command was working &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A full descriptive view of my PR can be found &lt;a href="https://github.com/DiceDB/dice/pull/975" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Contributing to DiceDB this week provided me with valuable insights into in-memory databases and the HyperLogLog data structure. By auditing and updating the documentation for the PFMERGE command, I ensured that DiceDB's documentation remains accurate and user-friendly&lt;/p&gt;

</description>
      <category>database</category>
      <category>redis</category>
      <category>opensource</category>
      <category>hacktoberfest</category>
    </item>
  </channel>
</rss>
