<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emil Valeev</title>
    <description>The latest articles on DEV Community by Emil Valeev (@emil_valeev).</description>
    <link>https://dev.to/emil_valeev</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%2F25183%2F310189e7-ccc8-4236-867d-2245c5a9a69e.jpg</url>
      <title>DEV Community: Emil Valeev</title>
      <link>https://dev.to/emil_valeev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emil_valeev"/>
    <language>en</language>
    <item>
      <title>🎉 Happy New Year, Neva Community! 🎉</title>
      <dc:creator>Emil Valeev</dc:creator>
      <pubDate>Wed, 31 Dec 2025 14:26:51 +0000</pubDate>
      <link>https://dev.to/emil_valeev/happy-new-year-neva-community-c26</link>
      <guid>https://dev.to/emil_valeev/happy-new-year-neva-community-c26</guid>
      <description>&lt;p&gt;Hi everyone! Emil Valeev here — the creator of the &lt;a href="https://github.com/nevalang/neva" rel="noopener noreferrer"&gt;Neva programming language&lt;/a&gt;. As the year draws to a close, I want to extend a heartfelt &lt;em&gt;thank you&lt;/em&gt; to all of you who took part in this journey. Your feedback, contributions, and curiosity power this project forward — even when the road gets tough, or when Neva isn’t making headlines (or money!).&lt;/p&gt;

&lt;p&gt;For a slightly bigger-picture take on why I believe Neva (and dataflow programming) matters, check out my recent article: &lt;a href="https://dev.to/emil_valeev/how-programming-will-look-in-the-future-5bj4"&gt;How Programming Will Look In the Future?&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2025: A Big Year for Neva
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Personal recap:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This year was a rollercoaster. I stepped outside open source and tried building a SaaS — learned a lot, but it didn’t pay the bills. That sent me back to job searching…but deep down, it was clear that &lt;em&gt;I just couldn’t quit Neva&lt;/em&gt;. In March, the project officially went on “freeze,” but by September, I was hacking away again. The result? &lt;em&gt;2025 turned out to be huge for Neva.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Actually Changed in 2025?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core Language:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduced &lt;em&gt;tagged unions&lt;/em&gt; (replacing enums!)&lt;/li&gt;
&lt;li&gt;Rewrote overloading for clarity and flexibility&lt;/li&gt;
&lt;li&gt;Prototyped Go interoperability: Go code can call Neva, and the compiler is starting to use this already (parts of the Go codebase even got rewritten in Neva)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are foundational steps — unblocking Neva’s evolution as a language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Toolchain:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IR visualization in &lt;code&gt;threejs&lt;/code&gt; and &lt;code&gt;mermaid&lt;/code&gt; formats&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;neva doc&lt;/code&gt;: Easily look up standard library docs (third-party support coming!)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;neva run --watch&lt;/code&gt;: Live reloading for development&lt;/li&gt;
&lt;li&gt;Richer &lt;code&gt;trace.log&lt;/code&gt; diagnostics&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--emit-ir&lt;/code&gt; flag for builds and runs&lt;/li&gt;
&lt;li&gt;New cross-compilation support: &lt;code&gt;loongarch&lt;/code&gt; arch, plus &lt;code&gt;target-os&lt;/code&gt;/&lt;code&gt;target-arch&lt;/code&gt; flags and a handy &lt;code&gt;osarch&lt;/code&gt; command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stdlib:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New &lt;code&gt;errors&lt;/code&gt; package: &lt;code&gt;errors.New&lt;/code&gt;, &lt;code&gt;errors.Must&lt;/code&gt;, &lt;code&gt;errors.Lift&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Support for &lt;code&gt;.env&lt;/code&gt; files (&lt;code&gt;os.LoadEnv&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Powerful new stream combinators: &lt;code&gt;streams.ZipMany&lt;/code&gt;, &lt;code&gt;streams.Wait&lt;/code&gt;, &lt;code&gt;strings.Join&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Internal/Infra:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactored and optimized all over—deadlocks/races fixed, code restructured, new tests (unit, integration, e2e, and smoke tests!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;People:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎉 Welcome new contributors:

&lt;ul&gt;
&lt;li&gt;k1ngmang
&lt;/li&gt;
&lt;li&gt;mike
&lt;/li&gt;
&lt;li&gt;WoodyAtHome
&lt;/li&gt;
&lt;li&gt;敖律风
&lt;/li&gt;
&lt;li&gt;Ikko Eltociear Ashimine
&lt;/li&gt;
&lt;li&gt;Zen
&lt;/li&gt;
&lt;li&gt;hardliner66
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;And thanks to everyone (big or small!)&lt;/em&gt; whose issues, code, or thoughts made Neva better.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Donations:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Set up &lt;a href="https://opencollective.com/nevalang" rel="noopener noreferrer"&gt;Open Collective&lt;/a&gt; — and got the very first donation! It might seem small, but for me, it’s a symbolic “we exist” moment (equals my first SaaS dollar… Feels real!).&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Ahead for 2026?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Language Philosophy
&lt;/h3&gt;

&lt;p&gt;After a lot of reflection, I realized: Neva’s biggest struggles often came from trying to blend a pure, parallel dataflow and visual-node philosophy with text syntax features inspired by control-flow languages. That tension led to confusion — and extra complexity.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For 2026, I’m doubling down on Neva’s strengths: minimalism, explicit components and nodes, ports, and message passing. This is what makes Neva different — and valuable! (I wrote a bit more on this in &lt;a href="https://github.com/nevalang/neva/issues/963" rel="noopener noreferrer"&gt;this GitHub issue&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Roadmap:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;a href="https://github.com/nevalang/neva/issues/970" rel="noopener noreferrer"&gt;Visual Node Editor&lt;/a&gt;: The “WOW!” feature that will let everyone &lt;em&gt;see&lt;/em&gt; the dataflow&lt;/li&gt;
&lt;li&gt;[ ] &lt;a href="https://github.com/nevalang/neva/issues/977" rel="noopener noreferrer"&gt;Debugger Prototype&lt;/a&gt;: Even a concept or POC would be a breakthrough&lt;/li&gt;
&lt;li&gt;[ ] &lt;a href="https://github.com/nevalang/neva/issues/973" rel="noopener noreferrer"&gt;Documentation Generator&lt;/a&gt;: Live/local docs to make onboarding &amp;amp; learning easier&lt;/li&gt;
&lt;li&gt;[ ] &lt;a href="https://github.com/nevalang/neva/issues/976" rel="noopener noreferrer"&gt;Call Go from Neva&lt;/a&gt;: Finish cross-language interop, more compiler logic in Neva itself&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Finalize language core:&lt;/strong&gt; numeric types, bytes, pattern matching, dataflow primitives, type assertions. Aim: “the language core is stable and won’t break”!&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Grow the stdlib:&lt;/strong&gt; IO, stream abstractions, error handling for stream processors, JSON, HTTP servers, state &amp;amp; context APIs, iterators/generators, and more.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Absolute reliability:&lt;/strong&gt; The compiler should &lt;em&gt;never&lt;/em&gt; crash (all fatal bugs fixed by EOY). Compiler errors should always be actionable and clear.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Code Quality:&lt;/strong&gt; Elevate maintainability across the board—compiler (especially type system, analyzer, desugarer) and runtime alike&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community &amp;amp; Growth
&lt;/h3&gt;

&lt;p&gt;Neva’s big ambition is only possible if &lt;em&gt;you&lt;/em&gt; join in! There’s no other language combining strong static typing, dataflow, and built-in parallelism in quite this way. In 2026, I want to focus more on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Community (website, Discord, Reddit, Twitter, Hacker News, donation platforms, maybe investors)&lt;/li&gt;
&lt;li&gt;Listening: &lt;em&gt;Why did you get interested in Neva? What do you want to build?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Showcasing your stories and creations!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want more context about dataflow and why I see Neva as pioneering “the future of programming,” check out &lt;a href="https://dev.to/emil_valeev/how-programming-will-look-in-the-future-5bj4"&gt;this dev.to post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thank you for a wild, emotional, progress-filled year. Here’s to bigger, bolder things for Neva in 2026, together!&lt;/p&gt;

&lt;p&gt;—Emil&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>go</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>HTMX, AlpineJS, SSR v1/2/3 and SPA | Easy missing guide.</title>
      <dc:creator>Emil Valeev</dc:creator>
      <pubDate>Wed, 06 Aug 2025 08:50:12 +0000</pubDate>
      <link>https://dev.to/emil_valeev/htmx-alpinejs-ssr-v123-and-spa-easy-missing-guide-2d7f</link>
      <guid>https://dev.to/emil_valeev/htmx-alpinejs-ssr-v123-and-spa-easy-missing-guide-2d7f</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;HTMX and AlpineJS are two JS libraries that extend HTML with special attributes and allow you to build frontend interfaces without SPA frameworks.&lt;/p&gt;

&lt;p&gt;They are alternatives to React/Vue/Angular and the like. Their emergence is a response to fatigue from the complex JS ecosystem and nostalgia for the times when problems were solved with PHP and jQuery.&lt;/p&gt;

&lt;p&gt;All my life I’ve written JSON APIs and SPA interfaces, and my brain struggled to understand why these libraries are needed and how to use them. That's why I wrote this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTMX vs AlpineJS — What Do They Handle?
&lt;/h2&gt;

&lt;p&gt;These two libraries have some overlap in functionality, but each generally solves its own problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt;: For making AJAX requests to the server, receiving HTML, and dynamically updating parts of the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AlpineJS&lt;/strong&gt;: For logic tied to local client state. All sorts of &lt;code&gt;isVisible&lt;/code&gt; flags, conditional rendering, etc. In short, anything that exists only on the client.
Another way to think about it — HTMX connects the frontend with the database (through the server API), and AlpineJS is a convenient way to have state on the frontend and render the UI dynamically from it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Server Side Rendering vs SPA
&lt;/h2&gt;

&lt;p&gt;Disclaimer: Terms v1 and v2 are my own.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSR v1 (Web 2.0, PHP era)
&lt;/h3&gt;

&lt;p&gt;Classic server-side rendering existed before the term itself became popular, simply because there was no other kind of rendering.&lt;/p&gt;

&lt;p&gt;This is when the client makes a request to the server, the server returns an HTML document, and the client (browser) fully redraws the entire page. The user experiences a "reload".&lt;/p&gt;

&lt;p&gt;This was typical for Web 2.0 era sites, and such UX is no longer considered high quality because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's not responsive enough.&lt;/li&gt;
&lt;li&gt;It doesn't support local state — all state is stored on the server. Anything you entered in a form, any menus you opened, all will be reset after a page reload.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SPA (Single Page Applications, ReactJS era)
&lt;/h3&gt;

&lt;p&gt;As a response to the problems of SSR v1 and Web 2.0, SPAs (Single Page Apps) appeared.&lt;/p&gt;

&lt;p&gt;This is a confusing name because, from the user's perspective, a site/app can have as many pages as needed.&lt;/p&gt;

&lt;p&gt;"Single page" here is in a purely technical sense. It means that now we have a single HTML document (page) and the entire UI is rendered dynamically via JavaScript.&lt;/p&gt;

&lt;p&gt;This solved the two problems above but created a bunch of new ones. There was now a lot more logic on the client, but the technologies for this were not ready. JavaScript was designed for writing small scripts and didn’t scale well as codebases grew.&lt;/p&gt;

&lt;p&gt;In response, other technologies started to appear, such as TypeScript and bundlers like Webpack (and modern alternatives), linters, test runners, package managers, etc. All of this infrastructure was fragmented, with no official support from language authors (unlike Go), requiring developers to maintain it themselves.&lt;/p&gt;

&lt;p&gt;This led to the situation where the person responsible for the frontend also had to handle “build” tooling. There are a lot of tools to master and configure, and some of them periodically break backwards compatibility.&lt;/p&gt;

&lt;p&gt;In short, frontend became very complex. And this complexity wasn’t from the tasks themselves, but from the low quality of the tools, which developers had to fight endlessly instead of just solving business problems.&lt;/p&gt;

&lt;p&gt;Add to this the fact that in the JS world, every weekend a new framework pops up, and the ecosystem is constantly shifting and changing.&lt;/p&gt;

&lt;p&gt;All this led to “JS fatigue” (c).&lt;/p&gt;

&lt;h3&gt;
  
  
  SSR v2 (NextJS era)
&lt;/h3&gt;

&lt;p&gt;I won’t call it Web 3.0 since that term is more about decentralization.&lt;/p&gt;

&lt;p&gt;Server-side rendering v2 wasn’t about JS fatigue, but about solving a technical problem — search engine indexing.&lt;/p&gt;

&lt;p&gt;When SPAs appeared, search crawlers weren’t adapted for such sites. They still expected the server to return static HTML, but instead got HTML with nothing in it, requiring JavaScript execution to render content.&lt;/p&gt;

&lt;p&gt;Modern crawlers can handle this, but server-side rendering is still preferred for SEO. Search indexing is complex, with many nuances. Let’s just accept the fact that:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SEO &amp;lt;3 SSR&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, on one hand, we want dynamic SPA interfaces, on the other we want static HTMX for SEO, as if we had SSR. What to do?&lt;/p&gt;

&lt;p&gt;The industry made a full circle back to server-side rendering, but now using different technologies.&lt;/p&gt;

&lt;p&gt;Previously, a PHP server would query the database, generate HTML via a templater, and return it to the client. Now, a NodeJS server runs JS inside the HTML page to generate static HTML and send it to the client. This way, we could keep using SPA frameworks like React and have lots of client-side logic, but the initial HTML received by the browser wasn't empty — it had meaningful content for indexing.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTMX and AlpineJS as a Cure for JS Fatigue
&lt;/h2&gt;

&lt;p&gt;Technically, the latest evolution solved all problems except one — there’s still too much JavaScript, and it’s still unpleasant and complex to write. “Unpleasant and complex,” by the way, isn’t just a vibe, it’s direct business damage. As your codebase grows, it becomes harder to change, so development gets more expensive. Fatigue converts directly into money because both are about energy.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTMX as SSR v3
&lt;/h3&gt;

&lt;p&gt;Disclaimer: SSR v3 is my own term.&lt;/p&gt;

&lt;p&gt;HTMX philosophy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modern frontend is often unjustifiably complex. We should try to return to the origins of server-side rendering.&lt;/li&gt;
&lt;li&gt;In the early web, there was the idea of Hypermedia — linking documents via hyperlinks, and the browser as the engine loading them. Think tags like &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; that could make requests without JavaScript. Unfortunately, the modern web moved away from this and became JS-heavy.&lt;/li&gt;
&lt;li&gt;Returning to pure SSR v1 is impossible, because the modern world really does require more responsive interfaces. The compromise invented was fragments — let the server return HTML as before, but not the whole page, just its “fragment,” which JavaScript can insert/replace in-place. As a result, only part of the UI is rerendered for the user, as if it were an SPA. At the same time, it’s true server-side rendering, with all its advantages.&lt;/li&gt;
&lt;li&gt;This led to a JS library that extends (HTMX = HTML eXtended) standard HTML with a small set of extra attributes, making any tags hypermedia, not just forms and links.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HTMX vs SPA — A Paradigm Shift
&lt;/h3&gt;

&lt;p&gt;By now, it should be clear, but I’ll spell it out, as my SPA-optimized brain didn’t grasp it at first.&lt;/p&gt;

&lt;p&gt;HTMX and SPA (React and others) imply different approaches to application architecture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPA&lt;/strong&gt;: The server returns structured data (usually JSON), and the client renders HTML based on that data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt;: The server returns HTML, and the client just inserts/replaces this HTML on the current page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is, rendering logic moves from client to server.&lt;/p&gt;

&lt;p&gt;Technically, we have a set of HTTP endpoints returning HTML snippets and our client, which calls these endpoints in response to browser events (scroll to element, button click, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; There is no client state! Only server state.&lt;/p&gt;

&lt;p&gt;We move away from client SPA libraries like React, with their branching, loops, etc. All this logic goes back to the templater, just like the good old days!&lt;/p&gt;

&lt;p&gt;And we don’t write any JavaScript at all — only HTML with a few extra attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; HTMX is not a silver bullet. I’ll repeat — there’s no silver bullet. This approach has downsides and may not suit you. More on that later.&lt;/p&gt;

&lt;h3&gt;
  
  
  AlpineJS as the Missing Piece
&lt;/h3&gt;

&lt;p&gt;HTMX does nothing to help with client-side state. If you need some purely frontend logic (even something as simple as disabling a button under a custom condition), you’ll need to write JavaScript.&lt;/p&gt;

&lt;p&gt;You have three choices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go back to SPA (and maybe SSR v2), with all that entails.&lt;/li&gt;
&lt;li&gt;Write vanilla JavaScript, no libraries.&lt;/li&gt;
&lt;li&gt;Add a library — but not a full-blown SPA framework with build step, just something simpler.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AlpineJS fits exactly this niche. It brings back client-side state and lets you code frontend logic. Now you can disable that button under your custom condition, with branching, loops, etc., like you’re used to in React.&lt;/p&gt;

&lt;p&gt;It looks more like Vue than React, though. Alpine extends HTML with a few extra attributes, like HTMX, but with Alpine, you do write a little JavaScript (a lot less than going vanilla).&lt;/p&gt;

&lt;p&gt;Yes, native JavaScript is actually very low-level, as odd as that sounds. Its DOM API is imperative and verbose, and for many basic things needed in every project, you’d have to hand-code from scratch. It’s not like Go’s standard library, where the devs sat down and thought about the real-wo&lt;/p&gt;

&lt;h2&gt;
  
  
  HTMX + AlpineJS vs SPA. Downsides of SSR v3
&lt;/h2&gt;

&lt;p&gt;If you compare this approach to classic SPA (or SPA + SSR on something like Next), it might seem like this approach is all pros. You get the best of both worlds and don’t pull Node into your project. Of course, that’s not the case. There are situations where this stack isn’t suitable, and you’re better off with React or Next.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have a lot of complex client-side logic that can’t be moved to the server. A grotesque example is Figma. That’s way more of an “application” than a website. Extremely high interactivity and a need for low latency.&lt;/li&gt;
&lt;li&gt;Also, HTMX and AlpineJS don’t provide static typing like TypeScript does. If you want full type coverage between client and server, this stack isn’t for you. You may have typing at the template level (e.g., Templ if you code in Go), but from HTMX you can, for example, make requests to non-existent endpoints, reference non-existent DOM nodes, etc. Maybe there’s a solution in the community, but it’s not out of the box, so it won’t be as minimalist. Why you might want full typing is another question; it’s usually about codebase/team size. With AlpineJS, it’s exactly the same.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you like this article, support my open-source projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/nevalang/neva" rel="noopener noreferrer"&gt;https://github.com/nevalang/neva&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neurocult/agency" rel="noopener noreferrer"&gt;https://github.com/neurocult/agency&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>htmx</category>
      <category>alpinejs</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Ultimate Guide to Parallel Testing in Go: -p, -parallel, and t.Parallel() Demystified</title>
      <dc:creator>Emil Valeev</dc:creator>
      <pubDate>Thu, 13 Feb 2025 12:05:00 +0000</pubDate>
      <link>https://dev.to/emil_valeev/the-ultimate-guide-to-parallel-testing-in-go-p-parallel-and-tparallel-demystified-1c1o</link>
      <guid>https://dev.to/emil_valeev/the-ultimate-guide-to-parallel-testing-in-go-p-parallel-and-tparallel-demystified-1c1o</guid>
      <description>&lt;p&gt;Go has three ways to tweak parallelism in tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-parallel&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t.Parallel()&lt;/code&gt; function call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How many of you know what they do? Why do we need all three? :slight_smile: &lt;/p&gt;

&lt;p&gt;It turns out &lt;code&gt;-p&lt;/code&gt; controls "how many test packages can run in parallel," &lt;code&gt;-parallel&lt;/code&gt; determines "how many test functions inside a single test package can run in parallel," and finally, &lt;code&gt;t.Parallel()&lt;/code&gt; marks a test function, telling Go that it can be run in parallel with other functions in the same package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 1
&lt;/h2&gt;

&lt;p&gt;Example: Let's say we have 999 packages with 999 test functions each, but not a single test function uses &lt;code&gt;t.Parallel()&lt;/code&gt;. What will happen? &lt;/p&gt;

&lt;p&gt;Answer: &lt;code&gt;N&lt;/code&gt; test packages will run in parallel (where &lt;code&gt;N&lt;/code&gt; equals the number of CPU cores), but each package will run its test functions sequentially. So, &lt;code&gt;N&lt;/code&gt; test functions will run in parallel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 2
&lt;/h2&gt;

&lt;p&gt;Another example: same scenario, but we add &lt;code&gt;-p 1&lt;/code&gt;. What will happen? &lt;/p&gt;

&lt;p&gt;Answer: completely sequential execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 3
&lt;/h2&gt;

&lt;p&gt;One more example: same as before, but this time we add &lt;code&gt;t.Parallel()&lt;/code&gt;. Well, &lt;code&gt;t.Parallel()&lt;/code&gt; combined with &lt;code&gt;-p 1&lt;/code&gt; results in "only one package runs at a time, but &lt;code&gt;N&lt;/code&gt; test functions run in parallel," where &lt;code&gt;N&lt;/code&gt; is again the number of CPU cores.&lt;/p&gt;

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

&lt;p&gt;The most fine-grained control is achieved using all three: &lt;code&gt;-p X -parallel Y&lt;/code&gt; and &lt;code&gt;t.Parallel()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We need to be careful with stateful tests (as usual, state is the root of all evil, but it's impossible to avoid).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Neva Programming Language
&lt;/h2&gt;

&lt;p&gt;Go developer? Check out &lt;a href="https://github.com/nevalang/neva" rel="noopener noreferrer"&gt;Nevalang&lt;/a&gt; - it's a work-in-progress programming language built on top of Go, that fixes some of Go's issues such as data-races, nil pointer-dereference, etc. In 2025 it will have visual editor, Rust-like enums and much more. Eventually you will be able to call it from Go and vice-versa.&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%2F7uauj0oy8ehhfcia8jxy.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%2F7uauj0oy8ehhfcia8jxy.gif" alt="Image description" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interested? Give us a star and join our community. We need developers (not just gophers!) to contribute and test the language. Let's change programming together - Go is awesome but we can do even better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.gg/dmXbC79UuH" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://t.me/+H1kRClL8ppI1MWJi" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/nevalang/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/neva_language" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Programming Will Look In the Future?</title>
      <dc:creator>Emil Valeev</dc:creator>
      <pubDate>Tue, 21 Jan 2025 21:52:12 +0000</pubDate>
      <link>https://dev.to/emil_valeev/how-programming-will-look-in-the-future-5bj4</link>
      <guid>https://dev.to/emil_valeev/how-programming-will-look-in-the-future-5bj4</guid>
      <description>&lt;p&gt;Programming hasn't fundamentally changed since the 1940s. Most languages still follow the von Neumann paradigm: write sequential instructions and modify data in memory. Let's look at a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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;6&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Outputs: 15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple and familiar, right? But there's a problem. Modern computers aren't getting faster like they used to. Instead, they're getting more cores, and our traditional programming model isn't great at handling multiple cores efficiently.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Multi-Core Challenge
&lt;/h1&gt;

&lt;p&gt;We've tried to adapt with tools for concurrent programming. Take Go's goroutines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;
    &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"All done!"&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;These solutions help, but they introduce problems like race conditions, deadlocks, and complex state management. We're building on top of a paradigm that wasn't designed for parallel execution, and control-flow languages are inherently hard to visualize.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Different Approach: Data Flow Programming
&lt;/h1&gt;

&lt;p&gt;What if we could write programs differently? Imagine describing your program as a network of independent nodes that pass data to each other - no shared state, just data flowing through a system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything runs in parallel by default&lt;/li&gt;
&lt;li&gt;Data is immutable, preventing race conditions&lt;/li&gt;
&lt;li&gt;Program structure mirrors data flow&lt;/li&gt;
&lt;li&gt;Natural scaling across multiple cores&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Enter Nevalang
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/nevalang/neva" rel="noopener noreferrer"&gt;Nevalang&lt;/a&gt; does exactly that. It's a modern language built around dataflow that treats programs as message-passing graphs rather than sequences of instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { fmt }

def Main(start any) (stop any) {
    for_print For{Print}
    wait Wait
    ---
    :start -&amp;gt; 1..5 -&amp;gt; for_print -&amp;gt; wait -&amp;gt; :stop
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we define a component &lt;code&gt;Main&lt;/code&gt; that receives a &lt;code&gt;start&lt;/code&gt; signal and sends a &lt;code&gt;stop&lt;/code&gt; signal. It has two nodes: &lt;code&gt;for_print&lt;/code&gt; (a &lt;code&gt;For&lt;/code&gt; with &lt;code&gt;Print&lt;/code&gt; inside) and &lt;code&gt;wait&lt;/code&gt;. When started, it creates a stream of numbers 1-5, prints each through &lt;code&gt;for_print&lt;/code&gt;, waits for completion, and sends the &lt;code&gt;stop&lt;/code&gt; signal.&lt;/p&gt;

&lt;p&gt;Visualized:&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%2Frjjyj3pmcdf54qpsag6p.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%2Frjjyj3pmcdf54qpsag6p.png" alt="Image description" width="800" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nevalang represents a fundamental shift in programming, embracing a paradigm naturally suited for parallelism and visualization rather than fighting traditional programming limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/nevalang/neva" rel="noopener noreferrer"&gt;Try Nevalang on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The future of programming might not look like the past. As our hardware continues to evolve, our programming models need to evolve too. Nevalang shows us one exciting possibility for that future.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WARNING: Nevalang is currently in development and not yet production-ready. We're looking for contributors and early-adopters. Join!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;This is an ambitious project maintained by a small group of enthusiasts. &lt;strong&gt;Your support by joining us will show interest and motivate us to continue.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.gg/dmXbC79UuH" rel="noopener noreferrer"&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/nevalang/" rel="noopener noreferrer"&gt;&lt;strong&gt;Reddit&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://t.me/+H1kRClL8ppI1MWJi" rel="noopener noreferrer"&gt;&lt;strong&gt;Telegram&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/neva_language" rel="noopener noreferrer"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Please &lt;strong&gt;give us a star ⭐️&lt;/strong&gt; to increase our chances of getting into GitHub trends - the more attention Nevalang gets, the higher our chances of actually making a difference.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>discuss</category>
      <category>news</category>
    </item>
    <item>
      <title>🕵 Agency: The Go Way to AI. Part 1</title>
      <dc:creator>Emil Valeev</dc:creator>
      <pubDate>Sat, 25 Nov 2023 19:55:48 +0000</pubDate>
      <link>https://dev.to/emil_valeev/agency-the-go-way-to-ai-part-1-1lhe</link>
      <guid>https://dev.to/emil_valeev/agency-the-go-way-to-ai-part-1-1lhe</guid>
      <description>&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%2Ftxxlayz0p6tzcofebjcq.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%2Ftxxlayz0p6tzcofebjcq.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making AI Easy for Go Developers
&lt;/h2&gt;

&lt;p&gt;The growth of generative AI like the OpenAI API and local LLMs is reshaping app development. Python and JavaScript have plenty of tools for this, with LangChain being popular. However, Go developers have fewer options. LangChainGo, a Go version of LangChain, doesn't fit well with Go's style, and some also find LangChain itself to be too complex.&lt;/p&gt;

&lt;p&gt;Recognizing the need for a Go-friendly tool that’s simple yet powerful, we developed &lt;a href="https://github.com/neurocult/agency" rel="noopener noreferrer"&gt;Agency&lt;/a&gt;. This Go library, designed with a clean approach, matches Go's strengths in a static type system and high performance. It's our answer to bringing easy-to-use, efficient AI capabilities to Go developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example - Continue Text
&lt;/h2&gt;

&lt;p&gt;Let's start from the simplest possible example - chat completion. For simplicity, we'll break it down piece by piece and then combine it into a single, cohesive example.&lt;/p&gt;

&lt;p&gt;First, we need to create &lt;code&gt;provider&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YOUR_OPENAI_API_KEY"&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;Provider is a &lt;em&gt;set of operations&lt;/em&gt; implemented by some external service. In this case, it's OpenAI.&lt;/p&gt;

&lt;p&gt;Note that we passed this &lt;code&gt;Params&lt;/code&gt; struct. In case of local LLM (must have OpenAI-compatible API) we can pass &lt;code&gt;openai.Params{BaseURL: "YOUR_SERVICE_URL_HERE"}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we have a provider, it's time to create an operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;TextToText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextToTextParams&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"gpt-3.5-turbo"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;SetPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You are a helpful assistant that translates English to French"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;TextToText&lt;/code&gt; method that we call is an &lt;em&gt;operation-builder&lt;/em&gt; - a function that takes some params and returns an operation, a value of type &lt;code&gt;agency.Operation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operations are basic building blocks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This one operation-builder has this signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;TextToText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="n"&gt;TextToTextParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;agency&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;TextToTextParams&lt;/code&gt; struct is specific to concrete provider and operation-builder. It depends on what external service provider uses and what functionality (modality) it implements. Almost any provider/builder allows to specify &lt;code&gt;Model&lt;/code&gt; but we'll see differences later on.&lt;/p&gt;

&lt;p&gt;For example, Anthropic provider could have different params than OpenAI and &lt;code&gt;openai.SpeechToText&lt;/code&gt; operation-builder will also have different params because of using different models under the hood than text to text (whisper instead of GPT).&lt;/p&gt;

&lt;p&gt;Now see this &lt;code&gt;SetPrompt("You are a helpful assistant that translates English to French")&lt;/code&gt; line? This is how we &lt;em&gt;configure&lt;/em&gt; operations. In this case we configure prompt that will be used.&lt;/p&gt;

&lt;p&gt;Okay, it looks like it's time to talk about what operations really are. Let's dig into the library source code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Operation is basic building block.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Operation&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="n"&gt;OperationHandler&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;OperationConfig&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// OperationHandler is a function that implements the actual logic.&lt;/span&gt;
&lt;span class="c"&gt;// It could be thought of as an interface that providers must implement.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;OperationHandler&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;OperationConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// OperationConfig represents abstract operation configuration.&lt;/span&gt;
&lt;span class="c"&gt;// It contains fields for all possible modalities but nothing specific to concrete model implementations.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;OperationConfig&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Prompt&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Messages&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time of writing, the library has version v0.1.0 and is under active development, so implementation details may change, but the main idea should remain - operation consist of &lt;em&gt;handler&lt;/em&gt; and &lt;em&gt;config&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Handler is a function implements actual logic. It's signature (just like commentary says) could be "thought of as an interface that providers must implement".&lt;/p&gt;

&lt;p&gt;Now let's look at what this &lt;code&gt;SetPrompt("...")&lt;/code&gt; method does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SetPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. It simply configures the operation and implements templating via &lt;code&gt;fmt.Sprintf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Are you still here with me? We're almost finished! The scariest stuff is behind.&lt;/p&gt;

&lt;p&gt;Actually, our operation is ready to use! Now we need to use something as an input for our operation, right? Let's create a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;agency&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I love programming."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We aren't scared of digging into the source code, are we? Here's the &lt;code&gt;UserMessage&lt;/code&gt; implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserRole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&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;That's right, it's just a tiny helper for &lt;code&gt;Message&lt;/code&gt;. What's that? It's an abstract message that represents any possible message that operations operates on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Role&lt;/span&gt;    &lt;span class="n"&gt;Role&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We already saw this message before, in operation's definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;OperationConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is - &lt;strong&gt;operation is a function that takes message as an input and returns message as an output.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's execute our operation and see what happens!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&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;Now let's put it all together!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OPENAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;TextToText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextToTextParams&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"gpt-3.5-turbo"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;SetPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You are a helpful assistant that translates English to French"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;agency&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I love programming."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to insert your OpenAI API key. Here's my output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;J'adore la programmation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like it works! You can of course rewrite this in a tighter manner if you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YOUR_OPENAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;TextToText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextToTextParams&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"gpt-3.5-turbo"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;SetPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You are a helpful assistant that translates English to French"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;agency&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I love programming."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all for now! Thank you very much for reading this. If you find any mistakes, please leave a comment. Link to this and many more working examples as well as link to the library itself gonna be below.&lt;/p&gt;

&lt;p&gt;We want to create the best library in the field and we need help. Feature-requests, bug-reports and of course pull-requests are more than welcome. We'll try to provide feedback as soon as possible.&lt;/p&gt;




&lt;p&gt;In the next series, we will explore topics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to create ChatGPT-like application in 40 lines of code&lt;/li&gt;
&lt;li&gt;How to combine operations in chains to execute them sequentially &lt;/li&gt;
&lt;li&gt;How to create custom operations&lt;/li&gt;
&lt;li&gt;How to use interceptors to observe operation-chains&lt;/li&gt;
&lt;li&gt;How to use prompt-templating&lt;/li&gt;
&lt;li&gt;How to use different modalities (speech, images, etc)&lt;/li&gt;
&lt;li&gt;How to implement RAG (using vector databases)&lt;/li&gt;
&lt;li&gt;... And many more!&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/neurocult/agency" rel="noopener noreferrer"&gt;Agency github repo&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neurocult/agency/blob/main/examples/translate_text/main.go" rel="noopener noreferrer"&gt;This example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neurocult/agency/tree/main/examples" rel="noopener noreferrer"&gt;Other examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>openai</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
