<?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: Fusen</title>
    <description>The latest articles on Forem by Fusen (@fus3n).</description>
    <link>https://forem.com/fus3n</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%2F1234883%2F78dfb879-d643-4c11-ac4f-34b0a9e24e02.png</url>
      <title>Forem: Fusen</title>
      <link>https://forem.com/fus3n</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fus3n"/>
    <language>en</language>
    <item>
      <title>I Built My Own Programming Language and its Virtual Machine In Python &amp; Go!</title>
      <dc:creator>Fusen</dc:creator>
      <pubDate>Tue, 24 Jun 2025 20:25:57 +0000</pubDate>
      <link>https://forem.com/fus3n/i-built-my-own-programming-language-and-its-virtual-machine-in-python-3o5c</link>
      <guid>https://forem.com/fus3n/i-built-my-own-programming-language-and-its-virtual-machine-in-python-3o5c</guid>
      <description>&lt;p&gt;Ever looked at your code and wondered what &lt;em&gt;really&lt;/em&gt; happens when you hit "run"? I mean, deep down, past the libraries and frameworks, how does your &lt;code&gt;if&lt;/code&gt; statement actually... &lt;em&gt;if&lt;/em&gt;? That curiosity bug bit me hard, and it led me down a rabbit hole that ended with me building my own programming language and virtual machine from scratch, using nothing but Python. I call it Pyle.&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%2Fjzz3setdpcicwtbas4oo.jpg" 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%2Fjzz3setdpcicwtbas4oo.jpg" alt="Pyle Concept Image" width="800" height="405"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  So, Why Build a Whole Language?
&lt;/h3&gt;

&lt;p&gt;Pyle isn't here to compete with Python, JavaScript, or any of the giants. The world probably doesn't &lt;em&gt;need&lt;/em&gt; another programming language from me (&lt;em&gt;not to mention written in Python&lt;/em&gt;). But &lt;em&gt;I&lt;/em&gt; needed to build one. I wanted to tear away the layers of abstraction and see the guts. How does text turn into something a computer understands? How does &lt;code&gt;a + b&lt;/code&gt; actually work?&lt;/p&gt;

&lt;p&gt;Pyle is my personal laboratory for exploring these questions. It’s an educational project, first and foremost.&lt;/p&gt;

&lt;p&gt;But this isn't my first time creating a language. My journey started with &lt;a href="https://github.com/Fus3n/cupscript" rel="noopener noreferrer"&gt;CupScript&lt;/a&gt;, a classic tree-walk interpreter. I remember piecing it together, trying to absorb every detail from a YouTube series, making tweaks here and there but never feeling quite satisfied. Then came &lt;a href="https://github.com/Fus3n/fcl" rel="noopener noreferrer"&gt;FCL&lt;/a&gt; – more of a joke, really – where I took "functional programming language" so literally that &lt;em&gt;everything&lt;/em&gt; was a function. Good times.&lt;/p&gt;

&lt;p&gt;All of these were in Python, the language I knew best back then. But the itch to see how these concepts would perform in something faster was always there. That led to my third attempt, &lt;a href="https://github.com/Fus3n/dusl" rel="noopener noreferrer"&gt;DUSL&lt;/a&gt;. I had ambitions for DUSL, maybe for scripting or small automation tasks. Life, as it does, got in the way, and a million bugs remained unfixed.&lt;/p&gt;

&lt;p&gt;Through all this, I was aware of &lt;strong&gt;stack-based virtual machines&lt;/strong&gt;. I knew they were the engine behind many interpreted languages and generally faster than just walking an AST. But I hadn't dived deep. After finally taking that plunge and learning more, I started prototyping in Python again. And that’s how Pyle came to be. It's a stepping stone, really. The grand plan is to eventually rewrite Pyle in &lt;strong&gt;Go&lt;/strong&gt;, both for that performance boost and to deepen my own understanding of &lt;strong&gt;Go&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Update, wrote the &lt;strong&gt;Go&lt;/strong&gt; version here: &lt;a href="https://github.com/Fus3n/pyle" rel="noopener noreferrer"&gt;https://github.com/Fus3n/pyle&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  From Text File to Execution
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Lexer (or Tokenizer):&lt;/strong&gt; This is the first stop. Imagine it as a meticulous librarian who reads your &lt;code&gt;.pyle&lt;/code&gt; script character by character and groups them into meaningful "words" or &lt;strong&gt;tokens&lt;/strong&gt;. So, &lt;code&gt;let x = 10;&lt;/code&gt; becomes something like &lt;code&gt;KEYWORD(let)&lt;/code&gt;, &lt;code&gt;IDENTIFIER(x)&lt;/code&gt;, &lt;code&gt;OPERATOR(=)&lt;/code&gt;, &lt;code&gt;NUMBER(10)&lt;/code&gt;, &lt;code&gt;PUNCTUATION(;)&lt;/code&gt;. No understanding of what it &lt;em&gt;means&lt;/em&gt; yet, just breaking it down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Parser:&lt;/strong&gt; Now that we have tokens, the parser steps in. This stage is like a grammar expert. It takes the stream of tokens and tries to build a structured representation, an &lt;strong&gt;Abstract Syntax Tree (AST)&lt;/strong&gt;. Think of it as an upside-down tree where each node represents a part of your code's structure – an assignment, an expression, a function call. If your code doesn't make grammatical sense (like &lt;code&gt;let = x 10&lt;/code&gt;), the parser throws a fit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Compiler:&lt;/strong&gt; This is where the magic starts to get &lt;em&gt;really&lt;/em&gt; interesting. The compiler walks through the AST and translates it into a simpler, more machine-friendly language: &lt;strong&gt;Pyle Bytecode&lt;/strong&gt;. This isn't the machine code your CPU runs directly, but a custom set of instructions I designed specifically for Pyle's own little virtual brain. For instance, &lt;code&gt;echo(a + b)&lt;/code&gt; might become a sequence of opcodes like &lt;code&gt;PUSH_VAR(a)&lt;/code&gt;, &lt;code&gt;PUSH_VAR(b)&lt;/code&gt;, &lt;code&gt;ADD&lt;/code&gt;, &lt;code&gt;CALL_BUILTIN(echo)&lt;/code&gt;. Seeing my high-level Pyle code turn into these compact instructions was a huge "aha!" moment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Stack-Based Virtual Machine (VM):&lt;/strong&gt; This is the engine that actually &lt;em&gt;runs&lt;/em&gt; the bytecode. My Pyle VM is a stack-based machine. Imagine a stack of plates: it pushes values onto this stack, performs operations (like &lt;code&gt;ADD&lt;/code&gt; which takes the top two values, adds them, and pushes the result back), manages function calls, and generally brings the bytecode to life. It reads each bytecode instruction and does what it says.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What Can Pyle Actually Do?
&lt;/h3&gt;

&lt;p&gt;It's still a learning project, but Pyle can handle the basics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Variables (&lt;code&gt;let&lt;/code&gt; for mutable, &lt;code&gt;const&lt;/code&gt; for immutable)&lt;/li&gt;
&lt;li&gt;  Numbers, strings, booleans, and even arrays (lists)&lt;/li&gt;
&lt;li&gt;  The usual arithmetic (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;), logical (&lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;), and comparison operators&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;if/else&lt;/code&gt; statements, &lt;code&gt;while&lt;/code&gt; loops, and &lt;code&gt;for-in&lt;/code&gt; loops (with ranges for now)&lt;/li&gt;
&lt;li&gt;  Defining and calling your own functions, complete with &lt;code&gt;return&lt;/code&gt; statements and even keyword arguments!&lt;/li&gt;
&lt;li&gt;  A really fun one: &lt;code&gt;importpy("module_name")&lt;/code&gt; lets you import actual Python modules. So, &lt;code&gt;const math = importpy("math"); echo(math.pi);&lt;/code&gt; totally works! Most of this interactivity with python types is possible because of pythons dynamicity.&lt;/li&gt;
&lt;li&gt;  Some built-ins like &lt;code&gt;echo()&lt;/code&gt;, &lt;code&gt;len()&lt;/code&gt;, &lt;code&gt;scan()&lt;/code&gt; for input, and &lt;code&gt;perf_counter()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A Quick Showcase
&lt;/h3&gt;

&lt;p&gt;This example defines a function to check for prime numbers and then uses &lt;code&gt;importpy&lt;/code&gt; to get a random number to test. &lt;br&gt;
Using JavaScript syntax highlighter as the syntax is very similar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function to check if a number is prime&lt;/span&gt;
&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Let's use a Python module to get a random number&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;importpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;test_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Checking if&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;test_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is prime...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is a prime number!&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is not a prime number.&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;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--- Primes up to 20 ---&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;h3&gt;
  
  
  The Real Payoff: Understanding
&lt;/h3&gt;

&lt;p&gt;Building Pyle has been an incredible learning experience. It’s one thing to read about compilers or VMs, and another entirely to wrestle with operator precedence in your parser or debug your VM's stack handling. It’s given me a much deeper appreciation for the tools and languages I use every day.&lt;/p&gt;

&lt;p&gt;If you've ever been curious about what goes on under the hood, I can't recommend a project like this enough. It doesn't have to be perfect or feature-complete. The goal is the journey and the understanding you gain along the way.&lt;/p&gt;

&lt;p&gt;The whole thing is up on GitHub if you want to check it out: &lt;a href="https://github.com/Fus3n/pyle-python" rel="noopener noreferrer"&gt;https://github.com/Fus3n/pyle-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Written in Go version: &lt;a href="https://github.com/Fus3n/pyle" rel="noopener noreferrer"&gt;https://github.com/Fus3n/pyle&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>learning</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Gem-Assist: Your Command-Line Personal Assistant</title>
      <dc:creator>Fusen</dc:creator>
      <pubDate>Wed, 12 Mar 2025 09:55:52 +0000</pubDate>
      <link>https://forem.com/fus3n/gem-assist-your-command-line-personal-assistant-51g7</link>
      <guid>https://forem.com/fus3n/gem-assist-your-command-line-personal-assistant-51g7</guid>
      <description>&lt;p&gt;Hey everyone! I wanted to share a project I've been working on called &lt;strong&gt;Gem-Assist&lt;/strong&gt;. It's a command-line personal assistant that integrates both proprietary and local models to provide access to over 30+ tools. &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%2Fev4gsz4l8d4ellw9zkjk.gif" 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%2Fev4gsz4l8d4ellw9zkjk.gif" alt="Gem-Assist" width="1505" height="901"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gem-Assist&lt;/strong&gt; is a Python-based tool designed to help with a variety of tasks. Whether you need to fetch data, automate routines, or manage projects. It works seamlessly with popular AI models (using &lt;strong&gt;litellm&lt;/strong&gt;) and offers a wide range of tools to make your workflow smoother.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/Fus3n/gem-assist" rel="noopener noreferrer"&gt;Gem-Assist on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Integration&lt;/strong&gt;: Supports integration with popular AI models such as Gemini 2.0 Flash, Gemini API, Litellm, and Ollama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool-based architecture:&lt;/strong&gt; Equipped with a variety of tools for tasks like:

&lt;ul&gt;
&lt;li&gt;Web searching (DuckDuckGo)&lt;/li&gt;
&lt;li&gt;File system operations (listing directories, reading/writing files, etc.)&lt;/li&gt;
&lt;li&gt;System information retrieval&lt;/li&gt;
&lt;li&gt;Reddit interaction&lt;/li&gt;
&lt;li&gt;Running shell commands&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Customizable:&lt;/strong&gt; Easily configure the assistant's behavior and extend its capabilities with new tools.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Simple Chat Interface:&lt;/strong&gt; Interact with the assistant through a straightforward command-line chat interface.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Memory:&lt;/strong&gt; Can save notes between conversation and remember them.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Saving Conversation:&lt;/strong&gt; Save and load previous conversations.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Commands:&lt;/strong&gt; Supports creating/executing (code), use &lt;code&gt;/commands&lt;/code&gt; for more information.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Extension:&lt;/strong&gt; For now you are required to write some code to extend its capabilities like adding commands to &lt;code&gt;CommandExecutor&lt;/code&gt; or making new tools, there should be enough examples in &lt;code&gt;gem/builtin_commands.py&lt;/code&gt; for commands and &lt;code&gt;utility.py&lt;/code&gt; for tools&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To get started with Gem-Assist, clone the repository and follow the installation instructions provided in the README file. The default branch is &lt;code&gt;master&lt;/code&gt;, and you can find the latest updates and contributions from the community.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Fus3n/gem-assist
&lt;span class="nb"&gt;cd &lt;/span&gt;gem-assist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Community and Contributions
&lt;/h2&gt;

&lt;p&gt;Gem-Assist is an open-source project, and contributions are always welcome. Whether you're a developer, tester, or just someone with great ideas, you can contribute to the project by submitting issues, suggesting features, or creating pull requests.&lt;/p&gt;

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

&lt;p&gt;Gem-Assist is more than just a command-line tool; it's a comprehensive assistant designed to enhance productivity and streamline tasks. With its robust features and active development, it stands out as a useful tool for anyone looking to integrate AI into their daily workflow. It is ultimately made for you to customize, add more tools or commands to be as personalized as possible, as it is for me.&lt;/p&gt;

&lt;p&gt;For more information and to start using Gem-Assist, visit the &lt;a href="https://github.com/Fus3n/gem-assist" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope you find it useful!&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
