<?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: SupermanSpace</title>
    <description>The latest articles on DEV Community by SupermanSpace (@1geek).</description>
    <link>https://dev.to/1geek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1255055%2F176e8c4a-19b4-4007-93b0-13d2ad4b78e8.jpg</url>
      <title>DEV Community: SupermanSpace</title>
      <link>https://dev.to/1geek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/1geek"/>
    <language>en</language>
    <item>
      <title>Rebuilding DEV’s Community Buddy to Actually Take Actions</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Thu, 30 Jul 2026 15:57:27 +0000</pubDate>
      <link>https://dev.to/1geek/rebuilding-devs-community-buddy-to-actually-take-actions-2g8f</link>
      <guid>https://dev.to/1geek/rebuilding-devs-community-buddy-to-actually-take-actions-2g8f</guid>
      <description>&lt;p&gt;DEV recently added DEV Community Buddy BETA to the post editor, giving writers an AI assistant for Markdown, formatting, embeds, and community guidelines.&lt;/p&gt;

&lt;p&gt;The idea is useful. The execution still feels like a chatbot placed beside the editor.&lt;/p&gt;

&lt;p&gt;When I tested it, the assistant could explain how to complete a task, but it could not perform that task inside the writing workflow. It did not clearly show what part of the draft it could access, how long the conversation context would persist, or whether the session belonged to the current post. Opening the assistant also reduced the editor space and created a separate interface that competed with the writing experience.&lt;/p&gt;

&lt;p&gt;That made me curious about a larger question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What would DEV Community Buddy look like if it could understand the active draft and safely take actions inside the editor?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since DEV runs on &lt;a href="https://github.com/forem/forem" rel="noopener noreferrer"&gt;Forem&lt;/a&gt;, an open-source community platform, I downloaded the project and set it up locally. I then started integrating the open-source &lt;a href="https://github.com/YourGPT/copilot-sdk" rel="noopener noreferrer"&gt;YourGPT Copilot SDK&lt;/a&gt; to turn the assistant from a passive question-and-answer panel into an editor-aware copilot.&lt;/p&gt;

&lt;p&gt;The goal is not to replace DEV’s beta or dismiss an early experiment. It is to explore the next step: an assistant that can read the current writing context, rewrite selected text, insert Markdown, suggest tags, prepare cover-image prompts, and apply approved changes without forcing the writer to copy and paste everything manually.&lt;/p&gt;

&lt;p&gt;This post is that exploration: how I built it, how others can reproduce it, and how the same pattern can extend beyond the editor (stats, reading lists, account settings). Credit to &lt;a class="mentioned-user" href="https://dev.to/ben"&gt;@ben&lt;/a&gt; , &lt;a class="mentioned-user" href="https://dev.to/jess"&gt;@jess&lt;/a&gt; and everyone who maintains DEV and Forem—the open platform and editor this depends on. If the product team reads this, treat it as a field report: keep what helps, ignore what does not. Actionable tools in the draft (and later across the product) are the direction I found useful to implement and document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/lbasPlwGpmw"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem I was trying to solve
&lt;/h2&gt;

&lt;p&gt;DEV Community Buddy can already help with basic writing questions. It can explain Markdown, suggest wording, answer questions about DEV, and generate text inside the side panel.&lt;/p&gt;

&lt;p&gt;The limitation is what happens after the answer appears.&lt;/p&gt;

&lt;p&gt;I was not trying to build a better chatbot for brainstorming. I wanted the copilot to complete the small, repetitive actions that slow writers down while finishing a post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fill four relevant tags” → the tag fields are populated&lt;/li&gt;
&lt;li&gt;“Tighten this paragraph” → the selected paragraph is replaced&lt;/li&gt;
&lt;li&gt;“Add a TL;DR” → a formatted section appears at the top&lt;/li&gt;
&lt;li&gt;“Write an introduction for this title” → the title remains unchanged and the introduction is inserted into the body&lt;/li&gt;
&lt;li&gt;“Outline the remaining sections” → Markdown is added at the current cursor position&lt;/li&gt;
&lt;li&gt;“Convert this Mermaid diagram” → a PNG is generated and inserted into the post&lt;/li&gt;
&lt;li&gt;“Create a cover image” → the image is generated and connected to the article&lt;/li&gt;
&lt;li&gt;“Proofread this selection” → corrections are applied without replacing the rest of the draft&lt;/li&gt;
&lt;li&gt;“Add citations” → relevant sources are found and inserted in the correct format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A side panel that only returns text still leaves the writer with the same workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;select → ask → copy → paste → repair formatting → return to writing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is useful during ideation. It becomes friction when the draft is nearly complete.&lt;/p&gt;

&lt;p&gt;The important context already exists inside the product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Article title&lt;/li&gt;
&lt;li&gt;Tags&lt;/li&gt;
&lt;li&gt;Body content&lt;/li&gt;
&lt;li&gt;Selected text&lt;/li&gt;
&lt;li&gt;Cursor position&lt;/li&gt;
&lt;li&gt;Focused field&lt;/li&gt;
&lt;li&gt;Current draft&lt;/li&gt;
&lt;li&gt;Authentication and CSRF state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The copilot should use that state instead of asking the author to repeatedly describe or paste it.&lt;/p&gt;

&lt;p&gt;The design principle was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The model decides what should change. Product-side handlers decide how that change is safely applied.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model does not directly manipulate the page. It selects from a controlled set of tools such as &lt;code&gt;updateTags&lt;/code&gt;, &lt;code&gt;replaceSelection&lt;/code&gt;, &lt;code&gt;insertMarkdown&lt;/code&gt;, or &lt;code&gt;generateImage&lt;/code&gt;. Forem remains responsible for validating and applying each change.&lt;/p&gt;

&lt;p&gt;This creates a clear separation of responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The model interprets the author’s intent&lt;/li&gt;
&lt;li&gt;Client tools expose permitted product actions&lt;/li&gt;
&lt;li&gt;Forem handlers update the real interface&lt;/li&gt;
&lt;li&gt;Sensitive credentials remain on the server&lt;/li&gt;
&lt;li&gt;The author reviews the result inside the existing workflow&lt;/li&gt;
&lt;li&gt;Generated content does not need to be copied back manually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the difference between adding AI beside a product and making the product operable through AI.&lt;/p&gt;

&lt;p&gt;The implementation follows the client-tool pattern provided by the &lt;a href="https://copilot-sdk.yourgpt.ai/docs/tools/frontend-tools" rel="noopener noreferrer"&gt;YourGPT Copilot SDK&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Turned DEV Community Buddy Into an Action-Capable Copilot
&lt;/h2&gt;

&lt;p&gt;In my version, DEV Community Buddy is no longer a detached assistant that only returns suggestions inside a side panel.&lt;/p&gt;

&lt;p&gt;Using the YourGPT Copilot SDK, I connected Buddy to a controlled set of tools that can read the current article state and perform actions directly inside the DEV writing experience.&lt;/p&gt;

&lt;p&gt;Each tool is bound to a specific part of the post, including the title, tags, body, selected text, and media.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions connected to the article editor
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request&lt;/th&gt;
&lt;th&gt;What Buddy does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Set or improve the title&lt;/td&gt;
&lt;td&gt;Updates the &lt;strong&gt;title field&lt;/strong&gt; as plain text without adding a Markdown &lt;code&gt;#&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fill the tags&lt;/td&gt;
&lt;td&gt;Selects up to &lt;strong&gt;four relevant tags&lt;/strong&gt; through Forem’s existing chip interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write an introduction, outline, or section&lt;/td&gt;
&lt;td&gt;Inserts Markdown at the &lt;strong&gt;cursor&lt;/strong&gt;, &lt;strong&gt;start&lt;/strong&gt;, or &lt;strong&gt;end&lt;/strong&gt; of the article&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rewrite the full article&lt;/td&gt;
&lt;td&gt;Replaces the body only when the request clearly applies to the complete draft&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rewrite selected text&lt;/td&gt;
&lt;td&gt;Replaces only the highlighted text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make selected text shorter&lt;/td&gt;
&lt;td&gt;Condenses the selection without changing the surrounding content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proofread selected text&lt;/td&gt;
&lt;td&gt;Fixes grammar, spelling, and clarity in place&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add a TL;DR&lt;/td&gt;
&lt;td&gt;Generates and inserts a formatted &lt;code&gt;## TL;DR&lt;/code&gt; section at the top&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate a cover image&lt;/td&gt;
&lt;td&gt;Creates an article image and connects it to the publishing workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert Mermaid to PNG&lt;/td&gt;
&lt;td&gt;Renders a Mermaid diagram as an image and inserts it into the article&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add citations&lt;/td&gt;
&lt;td&gt;Finds relevant sources and inserts citations where they are needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continue writing&lt;/td&gt;
&lt;td&gt;Uses the existing draft and cursor position to extend the article naturally&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important difference is that every request maps to a real product action.&lt;/p&gt;

&lt;p&gt;Buddy does not simply return a paragraph and leave the author to decide where it belongs. It understands whether the result should update the title, populate the tag fields, replace selected text, or insert Markdown at a particular position.&lt;/p&gt;

&lt;h3&gt;
  
  
  Editor behavior that mattered in practice
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Replace only the selected text&lt;/td&gt;
&lt;td&gt;Prevents a small edit from accidentally changing the full draft&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert at the cursor, start, or end&lt;/td&gt;
&lt;td&gt;Adds content where the author expects it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add the TL;DR at the top&lt;/td&gt;
&lt;td&gt;Creates the correct article structure automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove a leading H1 from generated body content&lt;/td&gt;
&lt;td&gt;DEV already stores the title in a separate field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preserve the selected range&lt;/td&gt;
&lt;td&gt;Keeps the correct text available after focus moves to the copilot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use the real tag chip interface&lt;/td&gt;
&lt;td&gt;Preserves Forem’s existing validation and interaction patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply every action once&lt;/td&gt;
&lt;td&gt;Prevents duplicate text, repeated tags, or multiple insertions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep API keys off the client&lt;/td&gt;
&lt;td&gt;Ensures sensitive credentials remain on the server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Require controlled tools&lt;/td&gt;
&lt;td&gt;Limits the model to actions explicitly exposed by the product&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These details may sound small, but they determine whether the copilot feels reliable.&lt;/p&gt;

&lt;p&gt;Generating good text is only one part of the problem. The system must also know where that text belongs, what it is allowed to change, and how to apply the result without damaging the rest of the article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selection-aware editing
&lt;/h3&gt;

&lt;p&gt;The fastest editing workflow does not begin inside the copilot panel.&lt;/p&gt;

&lt;p&gt;The author highlights a sentence or paragraph and chooses an action from the contextual toolbar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rewrite&lt;/strong&gt; · &lt;strong&gt;Shorter&lt;/strong&gt; · &lt;strong&gt;Proofread&lt;/strong&gt; · &lt;strong&gt;Add citation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rewrite

&amp;gt; Ever wondered what actually happens inside a Transformer?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Farnw1b3fyge109kiyksd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Farnw1b3fyge109kiyksd.png" alt=" " width="799" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before the copilot opens, the editor stores the selected range. The model then returns an improved version, and the &lt;code&gt;apply_selection_edit&lt;/code&gt; tool replaces that exact range.&lt;/p&gt;

&lt;p&gt;The interaction works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The author highlights text&lt;/li&gt;
&lt;li&gt;The editor stores the selection range&lt;/li&gt;
&lt;li&gt;The author chooses an action&lt;/li&gt;
&lt;li&gt;The copilot receives the selected content&lt;/li&gt;
&lt;li&gt;The model generates the requested revision&lt;/li&gt;
&lt;li&gt;Forem replaces only the stored selection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Buddy does not need to be open before the author selects text.&lt;/p&gt;

&lt;p&gt;The user also does not need to copy the response, return to the editor, find the original paragraph, paste the new version, and repair the formatting.&lt;/p&gt;

&lt;p&gt;The change happens exactly where the writing already lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Draft-aware content insertion
&lt;/h3&gt;

&lt;p&gt;Buddy also understands that different types of generated content belong in different places.&lt;/p&gt;

&lt;p&gt;A title should update the title field.&lt;/p&gt;

&lt;p&gt;Tags should become chips.&lt;/p&gt;

&lt;p&gt;A TL;DR should appear near the top.&lt;/p&gt;

&lt;p&gt;A new section should be inserted at the cursor or added to the end.&lt;/p&gt;

&lt;p&gt;A full rewrite should replace the body only when the author clearly requests it.&lt;/p&gt;

&lt;p&gt;This avoids one of the most common problems with generic AI writing tools: they generate useful content without understanding the structure of the product receiving it.&lt;/p&gt;

&lt;p&gt;In my implementation, the model chooses the intended action, but Forem controls how that action is applied.&lt;/p&gt;

&lt;p&gt;For example, the model can request:&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;"tool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"insert_markdown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"cursor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"## How attention works&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&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;"tool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"update_tags"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&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="s2"&gt;"ai"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"machinelearning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"javascript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"tutorial"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client-side handler validates the request and updates the corresponding part of the editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Media generation inside the writing flow
&lt;/h3&gt;

&lt;p&gt;I also wanted Buddy to handle tasks that normally require leaving the editor.&lt;/p&gt;

&lt;p&gt;For Mermaid diagrams, the author can provide or select Mermaid syntax and ask Buddy to convert it into a PNG. The diagram is rendered, uploaded, and inserted back into the article as Markdown.&lt;/p&gt;

&lt;p&gt;For article visuals, Buddy can generate a cover image or supporting image based on the title and draft context.&lt;/p&gt;

&lt;p&gt;The goal is not merely to return an image prompt. The goal is to complete the usable workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand what image the article needs&lt;/li&gt;
&lt;li&gt;Generate or render the image&lt;/li&gt;
&lt;li&gt;Make the result available to the article&lt;/li&gt;
&lt;li&gt;Insert or assign it in the correct place&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the difference between explaining how to add media and actually helping the author add it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic tags and TL;DR generation
&lt;/h3&gt;

&lt;p&gt;Tags and summaries are small tasks, but they interrupt the final publishing flow.&lt;/p&gt;

&lt;p&gt;Buddy can analyse the title and article body, select up to four relevant DEV tags, and populate the existing tag fields.&lt;/p&gt;

&lt;p&gt;It can also generate a concise TL;DR and insert it at the top of the article using consistent Markdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## TL;DR&lt;/span&gt;

A concise summary of the article appears here.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The author can still edit or remove the result, but the mechanical work is already complete.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;Three processes:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdedui1tagwa7ta6w1cd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdedui1tagwa7ta6w1cd.png" alt=" " width="800" height="1140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tools run against product state&lt;/strong&gt; (DOM handlers for the form; later, APIs for member data). The model only emits tool names and arguments.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime uses official SSE&lt;/strong&gt; (&lt;a href="https://copilot-sdk.yourgpt.ai/docs/server" rel="noopener noreferrer"&gt;server docs&lt;/a&gt;), not raw plain text.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rails enforces session and CSRF.&lt;/strong&gt; Model keys stay on the Node process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Product-level extensions use the same spine. You change context and tools, not the overall shape.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to split responsibilities
&lt;/h2&gt;

&lt;p&gt;Long tool catalogs in the system prompt waste tokens and hurt tool choice. This split worked better:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;systemPrompt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Persona and product rules (e.g. title ≠ body H1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tool descriptions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Short when/how (one sentence when possible)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;body()&lt;/code&gt; each request&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Live snapshot (&lt;code&gt;article_state&lt;/code&gt;, later other &lt;code&gt;*_state&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;handlers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Validation and mutations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skills (optional)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Process notes, not DOM writes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Attach draft state every turn; do not call “read draft” on every greeting.
&lt;/li&gt;
&lt;li&gt;Keep internal tool instructions out of the visible user message.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then multi-part requests can become multiple tool calls in one turn (title + tags + body).&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup on local Forem
&lt;/h2&gt;

&lt;p&gt;Stack used: Forem + &lt;code&gt;@yourgpt/copilot-sdk&lt;/code&gt; / &lt;code&gt;@yourgpt/llm-sdk&lt;/code&gt; &lt;strong&gt;2.5.x&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Forem local environment (Ruby, Postgres, Redis, Node 20, Yarn)
&lt;/li&gt;
&lt;li&gt;Provider API key (Gemini used here)
&lt;/li&gt;
&lt;li&gt;Node runtime process alongside Rails
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @yourgpt/copilot-sdk @yourgpt/llm-sdk openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;
&lt;span class="nv"&gt;COPILOT_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.6-flash"&lt;/span&gt;
&lt;span class="nv"&gt;COPILOT_FALLBACK_MODELS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.5-flash-lite,gemini-3.5-flash,gemini-flash-lite-latest"&lt;/span&gt;
&lt;span class="nv"&gt;COPILOT_RUNTIME_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:3101/api/copilot/stream"&lt;/span&gt;
&lt;span class="nv"&gt;COPILOT_RUNTIME_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Primary model: &lt;strong&gt;gemini-3.6-flash&lt;/strong&gt;. Fallbacks help when the free tier returns &lt;strong&gt;429&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runtime
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn copilot:runtime
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://127.0.0.1:3101/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per request: parse body → restore Gemini thought signatures when needed → stream via &lt;code&gt;createRuntime&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rails
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s2"&gt;"/api/copilot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"copilot#chat"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authenticate the user, proxy to &lt;code&gt;COPILOT_RUNTIME_URL&lt;/code&gt;, stream &lt;code&gt;text/event-stream&lt;/code&gt;, map failures to short messages. Do not show provider internals (e.g. &lt;code&gt;thought_signature&lt;/code&gt;) in the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mount node: &lt;code&gt;#article-copilot-sdk-root&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pack: &lt;code&gt;app/javascript/packs/copilotSdk.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Keep &lt;strong&gt;&lt;code&gt;CopilotProvider&lt;/code&gt; mounted&lt;/strong&gt; when the dock is closed; only portal the panel when open. Selection actions need &lt;code&gt;sendMessage&lt;/code&gt; without the dock.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CopilotProvider&lt;/span&gt;
  &lt;span class="na"&gt;runtimeUrl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/api/copilot"&lt;/span&gt;
  &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;SYSTEM_PROMPT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;streaming&lt;/span&gt;
  &lt;span class="na"&gt;maxIterations&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-CSRF-Token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;csrfToken&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/event-stream&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="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="na"&gt;article_state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;collectArticleState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArticleEditorTools&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SelectionToolbar&lt;/span&gt; &lt;span class="na"&gt;onOpen&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openDock&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isOpen&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;createPortal&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BuddyPanel&lt;/span&gt; &lt;span class="na"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;closeDock&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CopilotProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tools
&lt;/h3&gt;

&lt;p&gt;Prefer JSON Schema on &lt;code&gt;inputSchema&lt;/code&gt;, short descriptions, and &lt;code&gt;{ success: true/false, … }&lt;/code&gt; from handlers.&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="nf"&gt;useTools&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;set_article_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Set the post title field (plain text, not markdown).&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;additionalProperties&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&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;clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cleanArticleTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&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;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setNativeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;titleEl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_aiResponseMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brief&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="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;insert_into_body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Insert body markdown (start|end|cursor). No leading H1; title is separate.&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;apply_selection_edit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Replace selected body text once (Rewrite/Shorter). New text only; do not call again.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;aiResponseMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Strip a single leading &lt;code&gt;# Title&lt;/code&gt; from body inserts so the title field is not duplicated.
&lt;/li&gt;
&lt;li&gt;On Rewrite/Shorter, store &lt;code&gt;{ start, end, text }&lt;/code&gt; before focus moves; clear after one successful apply to avoid retry loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CSS and build
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@source&lt;/span&gt; &lt;span class="s1"&gt;"../../../node_modules/@yourgpt/copilot-sdk/dist/**/*.{js,ts,jsx,tsx}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&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;yarn build:copilot-css &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checks
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/health&lt;/code&gt; reports the configured model
&lt;/li&gt;
&lt;li&gt;Create Post shows the launcher when logged in
&lt;/li&gt;
&lt;li&gt;Tags update as chips
&lt;/li&gt;
&lt;li&gt;Title / tags / body update in the form, not only in chat
&lt;/li&gt;
&lt;li&gt;Selection Rewrite works with the dock closed first
&lt;/li&gt;
&lt;li&gt;Body does not start with a duplicate H1 title
&lt;/li&gt;
&lt;li&gt;Gemini tool follow-ups do not return 400
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;app/javascript/article-form/components/CopilotSDK/index.jsx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/ArticleEditorTools.jsx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DOM&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/editorDom.js&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/SelectionToolbar.jsx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool UI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/ToolCards.jsx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;&lt;code&gt;services/copilot-runtime/server.mjs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;app/controllers/copilot_controller.rb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pack&lt;/td&gt;
&lt;td&gt;&lt;code&gt;app/javascript/packs/copilotSdk.js&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Docs: &lt;a href="https://copilot-sdk.yourgpt.ai/docs/getting-started" rel="noopener noreferrer"&gt;getting started&lt;/a&gt; · &lt;a href="https://copilot-sdk.yourgpt.ai/docs/server" rel="noopener noreferrer"&gt;server&lt;/a&gt; · &lt;a href="https://copilot-sdk.yourgpt.ai/docs/tools/frontend-tools" rel="noopener noreferrer"&gt;frontend tools&lt;/a&gt; · &lt;a href="https://copilot-sdk.yourgpt.ai/docs/tools/agentic-loop" rel="noopener noreferrer"&gt;agentic loop&lt;/a&gt; · &lt;a href="https://copilot-sdk.yourgpt.ai/docs/generative-ui" rel="noopener noreferrer"&gt;generative UI&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Gemini 3 tool follow-ups
&lt;/h2&gt;

&lt;p&gt;Gemini 3.x expects a &lt;strong&gt;thought signature&lt;/strong&gt; on function calls for follow-up turns (&lt;a href="https://ai.google.dev/gemini-api/docs/thought-signatures" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://ai.google.dev/gemini-api/docs/openai" rel="noopener noreferrer"&gt;OpenAI compatibility&lt;/a&gt;):&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="nl"&gt;"tool_calls"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"function"&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;"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;"apply_selection_edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"extra_content"&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;"google"&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;"thought_signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If history is rebuilt without &lt;code&gt;extra_content&lt;/code&gt;, the next request often fails with 400. Cache signatures by tool-call id while streaming, re-attach them on the next request, and normalize field names (&lt;code&gt;tool_calls&lt;/code&gt;, &lt;code&gt;tool_call_id&lt;/code&gt;). Prefer fixing that over permanently downgrading the model to avoid the issue.&lt;/p&gt;

&lt;p&gt;Multi-tool turns also hit rate limits more easily on free tiers. Surface a clear retry message; optional fallback models help.&lt;/p&gt;




&lt;h2&gt;
  
  
  Small product choices that improved the feel
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Toolbar messages: action label + quoted selection only
&lt;/li&gt;
&lt;li&gt;One apply per selection edit
&lt;/li&gt;
&lt;li&gt;Title in the title field; body without a leading H1
&lt;/li&gt;
&lt;li&gt;Short confirmation after tools
&lt;/li&gt;
&lt;li&gt;Keep title/tags/body tools available without deferred search on multi-step turns
&lt;/li&gt;
&lt;li&gt;Provider mounted whenever selection tools need &lt;code&gt;sendMessage&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;User-facing errors without provider jargon
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extending the same Copilots beyond writing
&lt;/h2&gt;

&lt;p&gt;The editor integration is one vertical. The reusable part is the loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authenticated SSE
&lt;/li&gt;
&lt;li&gt;Context on every request
&lt;/li&gt;
&lt;li&gt;Tools that change real product state
&lt;/li&gt;
&lt;li&gt;Short chat around those tools
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Other surfaces can reuse &lt;strong&gt;runtime + proxy + &lt;code&gt;CopilotProvider&lt;/code&gt;&lt;/strong&gt;. You swap the context object and the tool set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Editor                         Extension surfaces
──────                         ──────────────────
article_state                  stats_state | reading_state | account_state
set_article_title              summarize / list tools (read)
fill_tags                      pin_list / update_pref (write, often with confirm)
insert_into_body               navigate / open section
apply_selection_edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I did not fully implement stats, reading-list, or settings copilots. Below is a practical map so someone continuing from this work knows what to add.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rules that still apply
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Put live data in &lt;code&gt;body()&lt;/code&gt;, not a mandatory “read all” tool every turn&lt;/td&gt;
&lt;td&gt;Fewer wasted tool rounds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools only perform actions the member can already perform&lt;/td&gt;
&lt;td&gt;Matches product permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep tool descriptions short&lt;/td&gt;
&lt;td&gt;Better tool choice, smaller schemas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep user-visible messages free of internal instructions&lt;/td&gt;
&lt;td&gt;Clearer chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prefer one-shot mutations where possible&lt;/td&gt;
&lt;td&gt;Avoid loops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirm destructive or account-wide changes&lt;/td&gt;
&lt;td&gt;Especially settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Never put secrets in model context&lt;/td&gt;
&lt;td&gt;Tokens, passwords, raw session ids&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Stats
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; explain numbers the member can already see, and suggest a next writing step from real data—not invented metrics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context example:&lt;/strong&gt;&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="nx"&gt;body&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="na"&gt;surface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;stats_state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;30d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;followers_delta&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;top_posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;published_at&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;series&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;views&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;&lt;strong&gt;Example tools:&lt;/strong&gt; &lt;code&gt;get_stats_snapshot&lt;/code&gt;, &lt;code&gt;list_top_posts&lt;/code&gt;, &lt;code&gt;open_post_analytics&lt;/code&gt;, &lt;code&gt;suggest_followup_topics&lt;/code&gt; (text only from provided posts), optional bridge to editor tools for an outline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example questions:&lt;/strong&gt; why views changed; which posts to turn into a series; what to write next given top tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraint:&lt;/strong&gt; if a figure is not in context or a tool result, say so. Do not invent analytics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading list
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; build a short, personal queue from real posts (search/save/follow APIs), not hallucinated links.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context example:&lt;/strong&gt; followed tags, recent reads, saves, optional goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example tools:&lt;/strong&gt; &lt;code&gt;search_posts&lt;/code&gt;, &lt;code&gt;build_reading_list&lt;/code&gt;, &lt;code&gt;pin_reading_item&lt;/code&gt;, &lt;code&gt;save_for_later&lt;/code&gt;, &lt;code&gt;follow_tag&lt;/code&gt; / &lt;code&gt;mute_tag&lt;/code&gt; (with confirmation), &lt;code&gt;export_reading_list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example questions:&lt;/strong&gt; weekend list on a topic; next reads based on history; pin three and drop already-read items.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraint:&lt;/strong&gt; every recommended URL/id should come from a tool or injected state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Account and settings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; explain settings and, where safe, apply changes the member already has UI for—without dumping secrets into the prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context example:&lt;/strong&gt; profile completeness flags, notification toggles, 2FA on/off, session count—not passwords or raw tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example tools:&lt;/strong&gt; &lt;code&gt;open_settings_section&lt;/code&gt;, &lt;code&gt;update_notification_pref&lt;/code&gt; (confirm), &lt;code&gt;update_profile_field&lt;/code&gt; (confirm for public fields), &lt;code&gt;list_sessions&lt;/code&gt;, &lt;code&gt;revoke_session&lt;/code&gt; (confirm), &lt;code&gt;explain_setting&lt;/code&gt; (read-only).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example questions:&lt;/strong&gt; reduce email noise; complete public profile; review sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraint:&lt;/strong&gt; prefer navigate + explain by default; mutate only with confirmation (&lt;code&gt;needsApproval&lt;/code&gt; or equivalent). Stricter than the editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation order for an extension
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Choose one surface.
&lt;/li&gt;
&lt;li&gt;Define a &lt;code&gt;*_state&lt;/code&gt; payload you can collect safely.
&lt;/li&gt;
&lt;li&gt;Add a small tool pack (about 4–8 tools) with short descriptions.
&lt;/li&gt;
&lt;li&gt;Mount &lt;code&gt;CopilotProvider&lt;/code&gt; on that page; pass &lt;code&gt;surface&lt;/code&gt; + state in &lt;code&gt;body()&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Reuse the existing runtime and Rails proxy.
&lt;/li&gt;
&lt;li&gt;Adjust the system prompt for that surface only.
&lt;/li&gt;
&lt;li&gt;Test normal prompts and refusal cases (“delete my account” without a tool, etc.).
&lt;/li&gt;
&lt;li&gt;Optionally connect back to the editor (e.g. stats → outline → &lt;code&gt;insert_into_body&lt;/code&gt;).
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Prompt for an AI coding agent
&lt;/h2&gt;

&lt;p&gt;Paste this into Cursor, Claude Code, Codex, or similar when you want the agent to set up the same stack on a Forem (or similar) codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are implementing an editor-aware writing copilot on Forem using the YourGPT Copilot SDK
(@yourgpt/copilot-sdk + @yourgpt/llm-sdk ~2.5.x), matching this architecture:

ARCHITECTURE
- Browser: CopilotProvider (always mounted) + useTools handlers + SelectionToolbar
  + CopilotChat portaled in a right dock when open
- Rails: authenticated POST /api/copilot streams SSE to the Node runtime (CSRF + session)
- Node: services/copilot-runtime/server.mjs with createRuntime, Gemini 3.x primary model
  (COPILOT_MODEL=gemini-3.6-flash), thought_signature cache/restore on tool follow-ups,
  optional model fallbacks on 429
- Never put API keys in the client. Never stream text/plain to CopilotChat.

DOCS (prefer over memory)
- https://copilot-sdk.yourgpt.ai/docs/getting-started
- https://copilot-sdk.yourgpt.ai/docs/server
- https://copilot-sdk.yourgpt.ai/docs/tools/frontend-tools
- https://copilot-sdk.yourgpt.ai/docs/tools/agentic-loop
- https://copilot-sdk.yourgpt.ai/docs/generative-ui
- https://ai.google.dev/gemini-api/docs/thought-signatures

FILE MAP TO CREATE/UPDATE
app/javascript/article-form/components/CopilotSDK/
  index.jsx, SelectionToolbar.jsx, ArticleEditorTools.jsx, editorDom.js,
  ToolCards.jsx, toolSchemas.js
app/javascript/packs/copilotSdk.js
app/assets/stylesheets/copilot-sdk.css  (Tailwind @source SDK dist; FAB + dock + selection pill)
app/controllers/copilot_controller.rb
config/routes.rb → post "/api/copilot"
services/copilot-runtime/server.mjs
.env: GOOGLE_API_KEY, COPILOT_MODEL, COPILOT_RUNTIME_URL, COPILOT_FALLBACK_MODELS

UI REQUIREMENTS (match this UX)
- Floating launcher (avatar + BETA badge) bottom-right above article actions
- Right full-height dock (~400px) with official CopilotChat (csdk-theme-modern)
- Provider ALWAYS mounted; only dock portals when open; body class buddy-dock-open
- Selection toolbar on body highlight: Rewrite + Shorter only (no internal prompts in chat)
- User message format: "Rewrite\n\n&amp;gt; selected text" (blockquote). Tool policy in system
  prompt + tool descriptions, not in the bubble
- On toolbar click: setPendingBodySelection({start,end,text}), open dock, sendMessage
- apply_selection_edit once using pending range; clear pending; do not loop
- Live article_state (title, tags, body) in CopilotProvider body() every request
- Strip leading H1 from body inserts; title is a separate plain-text field
- Short friendly parseError messages; never show thought_signature to users
- toolRenderers for tags/cover/mermaid/TL;DR; ToolStep titles for simple tools
- local thread persistence key: dev-community-buddy-threads

TOOLS (inputSchema JSON Schema, short descriptions)
set_article_title, fill_tags, insert_into_body, replace_article_body,
apply_selection_edit (eager, one-shot), generate_tldr, generate_cover_image,
mermaid_to_png; optional get_article_draft (not on every greeting)

LAYERING
systemPrompt = persona + product rules only (no tool catalog)
tool descriptions = short decision boundaries
body() = live state
handlers = DOM mutations, return { success, ... }

VERIFY
yarn build:copilot-css &amp;amp;&amp;amp; yarn build
yarn copilot:runtime → curl health
Logged-in Create Post: launcher, tags chips, multi-tool title+tags+body,
selection Rewrite with dock closed first, no body H1 title, no 400 on tool follow-up

If something fails, fix signatures / selection pending range / Provider mount first—
do not downgrade Gemini major solely to hide tool-follow-up 400s unless the user asks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is this the official DEV Community Buddy?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No. This is an independent fan-built experiment using Forem. It is not affiliated with, endorsed by, or deployed by DEV.to Community. I built it to explore a more efficient and action-capable version of Buddy could look like, especially one that can understand the article context, work directly with the editor, and help developers write and publish with less manual effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did you build it on Forem?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
DEV Community at dev.to is built on Forem, its open-source community platform. After testing the first beta version of DEV Community Buddy, I found it useful for basic writing guidance, but it still behaved more like a chatbot than an integrated product copilot. I wanted to explore a more capable experience that could help developers write better posts with less manual work, so I ran the same Forem foundation behind dev.to locally and connected it to the YourGPT Copilot SDK. The SDK made it possible to turn Buddy into an action-capable copilot that understands the live article state and can safely interact with the real writing interface. Instead of only suggesting text, it can update the title, fill relevant tags, rewrite or proofread selected content, insert a TL;DR, generate images, convert Mermaid diagrams into PNGs, add citations, and place Markdown in the correct location. This allowed me to build a more contextual and efficient writing workflow inside the actual product, rather than a separate AI demo that could not operate the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What part of the project is actually implemented?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The editor copilot is implemented. It can work with the title, tags, article body, selected text, cursor position, TL;DR generation, Mermaid rendering, and media-related actions.&lt;/p&gt;

&lt;p&gt;The stats, personalised reading list, account, and settings copilots are proposed extensions of the same architecture. They are not presented as completed features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the YourGPT Copilot SDK?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The YourGPT Copilot SDK is an open-source framework for building AI copilots that can understand product context, use tools, and take actions inside an application. It provides the client components and runtime infrastructure for streaming conversations, frontend and backend tool execution, live application context, multi-step agent workflows, and generative UI. Rather than adding a standalone chatbot, it helps developers build a agentic copilot that is embedded into the product experience and can safely operate within the actions and permissions the application exposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use the YourGPT Copilot SDK instead of calling a model API directly?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A direct LLM API can generate text, but it does not automatically make an application agentic. The YourGPT Copilot SDK adds the orchestration layer required to build an action-capable AI copilot agent inside a product. It streams responses, passes live application context such as the current article title, tags, body, cursor position, and selected text, connects the model to controlled frontend tools, supports multi-step tool execution, and renders tool progress directly in the interface. This allows the copilot to do more than suggest content. It can safely update fields, replace selected text, insert Markdown, generate media, and complete approved actions on the user’s behalf. The core value of the SDK is not access to a particular AI model, but the infrastructure for turning model output into contextual, permissioned product actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use a different model?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. The architecture is model-independent. Gemini was used for this implementation, but another supported provider can be configured through the runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did you use Gemini for this build?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Gemini was the primary model used while developing and testing the integration. It supported the tool-calling and image gen workflow needed for editor actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use frontend tools for editor actions?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The relevant state already exists in the browser, including the current selection, cursor position, unsaved body content, and focused field.&lt;/p&gt;

&lt;p&gt;Frontend tools can operate on that live state without repeatedly saving the draft or sending unnecessary requests to the backend. Server-side tools are still more appropriate for protected data, external services, uploads, and account-level actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the copilot know what is in the current draft?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The application passes a structured article-state object with each request. It can include the title, tags, body, selected text, cursor position, and active surface.&lt;/p&gt;

&lt;p&gt;This gives the AI current product context without requiring the author to paste the article into the conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can the copilot modify anything in the application?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes, Copilot can take action on an application by using the exposed tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can this architecture work outside the DEV editor?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. The same runtime, authenticated proxy, provider, and tool pattern can support other product surfaces.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analytics explanations using &lt;code&gt;stats_state&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Personalised reading lists using real post-search tools&lt;/li&gt;
&lt;li&gt;Navigation and account assistance&lt;/li&gt;
&lt;li&gt;Notification preference management&lt;/li&gt;
&lt;li&gt;Profile updates with confirmation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main changes are the context object, available tools, and permission rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the YourGPT Copilot SDK limited to React applications?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The client components used in this implementation are React-based, but the broader architecture is not limited to a particular backend. The runtime and tool pattern can be integrated with applications using Rails, Node, or other server environments.&lt;/p&gt;

&lt;p&gt;The exact frontend integration depends on how the host application exposes state and actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can this be used in production?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Absolutely. Both Forem and the YourGPT Copilot SDK are open source, so you can clone the repositories, fork them, modify the code, self-host the complete stack, and adapt this implementation for your own product. The YourGPT Copilot SDK is available under the permissive MIT License, while Forem is released under the GNU Affero General Public License v3.0&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;I wanted to build a copilot that understands a draft as live product state, not just text inside a chat window. It should know the title, tags, body, cursor position, and selected text, choose from a controlled set of tools, apply the requested change in the correct place, and stop once the editor has been updated.&lt;/p&gt;

&lt;p&gt;That is what I built on a local Forem instance. The process also exposed the less visible problems behind an action-capable copilot: preserving selections after focus changes, preventing repeated tool execution, avoiding duplicate H1 titles, handling provider-specific tool follow-ups, and recovering cleanly from rate limits.&lt;/p&gt;

&lt;p&gt;The same architecture can extend beyond writing. By changing the context and available tools, the copilot could explain article performance, curate a personalised reading list, navigate product settings, or complete other approved actions across the platform.&lt;/p&gt;

&lt;p&gt;Forem’s open-source foundation made the experiment possible. The &lt;a href="https://github.com/YourGPT/copilot-sdk" rel="noopener noreferrer"&gt;YourGPT Copilot SDK&lt;/a&gt; provided the agentic application layer for streaming, context, tool execution, and product actions. I have included the architecture, implementation notes, checks, and extension paths so other developers can reproduce the editor integration, improve it, or adapt the same pattern to their own products.&lt;/p&gt;

&lt;p&gt;The larger lesson is simple: adding a chat panel gives users answers. Connecting an AI copilot to real product state and controlled tools gives them outcomes.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Great AWS Outage of October 2025: When the Internet's Backbone Buckled</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Mon, 20 Oct 2025 19:03:41 +0000</pubDate>
      <link>https://dev.to/1geek/the-great-aws-outage-of-october-2025-when-the-internets-backbone-buckled-207n</link>
      <guid>https://dev.to/1geek/the-great-aws-outage-of-october-2025-when-the-internets-backbone-buckled-207n</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%2Fyery0e19vfec3t0bwxh9.webp" 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%2Fyery0e19vfec3t0bwxh9.webp" alt="AWS DOWN" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;October 20, 2025&lt;/strong&gt; — In the early hours of Monday morning, millions of internet users worldwide woke up to find their favorite apps and services completely unavailable. Snapchat wouldn't load. Wordle was inaccessible. Medium not loading. Vercel was not working. Ring doorbells went dark. Amazon's own shopping site displayed error pages featuring apologetic dog photos. The culprit? A massive outage at Amazon Web Services (AWS), the cloud computing giant that quietly powers much of the modern internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scale of the Disruption
&lt;/h2&gt;

&lt;p&gt;The outage began at 12:11 a.m. PT (3:11 a.m. ET) when AWS reported an "operational issue" affecting 14 different services in its U.S.-East-1 Region center in northern Virginia. What started as a technical glitch in a single data center quickly cascaded into one of the largest internet disruptions since the CrowdStrike malfunction of 2024.&lt;/p&gt;

&lt;p&gt;Over 4 million users reported issues due to the incident, affecting an astonishing array of services that people rely on daily. The impact was both widespread and democratic in its chaos, bringing down everything from entertainment platforms to critical business infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Was Affected?
&lt;/h3&gt;

&lt;p&gt;The list of affected services reads like a who's who of the internet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Social Media &amp;amp; Communication:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snapchat&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;li&gt;Signal (encrypted messaging)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Fortnite&lt;/li&gt;
&lt;li&gt;Roblox&lt;/li&gt;
&lt;li&gt;Pokémon GO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Financial Services:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coinbase (cryptocurrency exchange)&lt;/li&gt;
&lt;li&gt;Venmo&lt;/li&gt;
&lt;li&gt;PayPal&lt;/li&gt;
&lt;li&gt;Robinhood&lt;/li&gt;
&lt;li&gt;Chime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Amazon's Own Services:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon.com (shopping)&lt;/li&gt;
&lt;li&gt;Prime Video&lt;/li&gt;
&lt;li&gt;Alexa&lt;/li&gt;
&lt;li&gt;Ring doorbells and security cameras&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Airlines:&lt;/strong&gt;&lt;br&gt;
United Airlines experienced disruptions to its app and website, with some internal systems also temporarily affected. Delta Airlines experienced a small number of minor flight delays.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Duolingo&lt;/li&gt;
&lt;li&gt;Canvas (online teaching platform)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other Major Services:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Canva (graphic design)&lt;/li&gt;
&lt;li&gt;Perplexity (AI search)&lt;/li&gt;
&lt;li&gt;Max (streaming)&lt;/li&gt;
&lt;li&gt;Apple Music&lt;/li&gt;
&lt;li&gt;Microsoft Teams (surprisingly affected despite Microsoft's own Azure cloud)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intercom (down from last 11 hours)&lt;/li&gt;
&lt;li&gt;YourGPT Helpdesk (not loading for 15 minutes)&lt;/li&gt;
&lt;li&gt;Ada (not working for 2 hours)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the United Kingdom, customers of banks including Lloyds, Bank of Scotland, and Halifax reported issues while attempting to log into their accounts. British government websites Gov.uk and HM Revenue and Customs also experienced disruptions, highlighting&lt;br&gt;
how critical infrastructure has become dependent on cloud services.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Root Cause: A DNS and Database Perfect Storm
&lt;/h2&gt;

&lt;p&gt;At 4:26 a.m. ET, Amazon flagged significant error rates for requests made to the DynamoDB endpoint in the US-EAST-1 Region. DynamoDB is AWS's database service that thousands of companies use to manage their data tables and indexes.&lt;/p&gt;

&lt;p&gt;The issue appeared to be related to DNS resolution of the DynamoDB API endpoint. DNS (Domain Name System) is essentially the internet's phonebook, translating human-readable website names into computer-readable IP addresses. When this system fails to communicate with databases, the entire chain of services collapses.&lt;/p&gt;

&lt;p&gt;At 11:43 a.m., AWS identified the root cause as "an underlying internal subsystem responsible for monitoring the health of our network load balancers". This technical fault in a monitoring system created a cascading failure that rippled through AWS's entire infrastructure.&lt;/p&gt;

&lt;p&gt;A software engineer and cyber expert noted that the issue appeared to be with one of the networking systems AWS uses to control a database product, highlighting how a problem in one small component can bring down an entire ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Recovery: A Long and Bumpy Road
&lt;/h2&gt;

&lt;p&gt;At 6:35 a.m. ET, AWS announced that the database problem was "fully mitigated" but warned there may still be delays. However, the recovery proved more complicated than initially hoped.&lt;/p&gt;

&lt;p&gt;Many sites came back online within a few hours, although Downdetector showed another spike in user reports around noon ET of outages at Amazon, AWS and Alexa. The initial fix didn't fully resolve all issues, and services continued to experience intermittent problems throughout the day.&lt;/p&gt;

&lt;p&gt;Around 1:30 p.m. ET, AWS said it was starting to see "early signs" of EC2 recovery in some regions and was applying fixes to remaining areas. The company's EC2 (Elastic Compute Cloud) service provides virtual server capacity that companies rely on to run their applications.&lt;/p&gt;

&lt;p&gt;Amazon.com itself wasn't spared from the chaos. Reports on Downdetector showed over 12,000 outages in the US, with Amazon displaying "something went wrong" error pages featuring various dogs to frustrated shoppers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact: Beyond Inconvenience
&lt;/h2&gt;

&lt;p&gt;While many users experienced mere inconvenience, the outage had more serious consequences for others:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business Disruption:&lt;/strong&gt; Warehouse and delivery employees, along with drivers for Amazon's Flex service, reported that internal systems were offline at many sites. Some warehouse workers were instructed to stand by in break rooms and loading areas during their shift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessibility Concerns:&lt;/strong&gt; One user shared a particularly poignant example of how cloud dependency affects vulnerable populations: "I use Alexa-enabled smart plugs to control the lamps in my room. I'm unable to walk without leaning on crutches so being able to turn lights and music on by voice is very helpful. During the outage my smart plugs became unresponsive".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Educational Impact:&lt;/strong&gt; Educational publishing company Folens contacted teachers advising that services linked to its 'My Folens' library were being disrupted, affecting students' access to learning materials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Concerns:&lt;/strong&gt; Ring experienced outages affecting thousands of users, creating problems for those who rely on Ring doorbells and security cameras for safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fragility of Centralized Infrastructure
&lt;/h2&gt;

&lt;p&gt;This outage underscores a fundamental vulnerability in how the modern internet is structured. The outage highlighted the fragility of companies that use cloud-based servers to host their data, and how suddenly businesses across the globe can be affected by an unplanned outage.&lt;/p&gt;

&lt;p&gt;AWS is the dominant player in cloud computing, making $107 billion in the 2024 financial year, representing 17% of Amazon's total revenue. This dominance means that when AWS experiences problems, the ripple effects are felt globally.&lt;/p&gt;

&lt;p&gt;Cori Crider, executive director of the Future of Technology Institute, stated: "Europe's dependency on monopoly cloud companies like Amazon is a security vulnerability and an economic threat we can't ignore", calling for European governments to diversify their cloud providers and support local alternatives.&lt;/p&gt;

&lt;p&gt;Charlotte Wilson, head of enterprise at Check Point Software Technologies, noted: "Today's outage is another reminder that the digital world doesn't stop at borders - a local fault can ripple worldwide in minutes".&lt;/p&gt;

&lt;h2&gt;
  
  
  Was It a Cyberattack?
&lt;/h2&gt;

&lt;p&gt;With such widespread disruption, speculation naturally turned to the possibility of malicious activity. However, Rob Jardin, chief digital officer at cybersecurity company NymVPN, stated: "There's no sign that this AWS outage was caused by a cyberattack - it looks like a technical fault affecting one of Amazon's main data centres".&lt;/p&gt;

&lt;p&gt;Rafe Pilling, director of threat intelligence at cybersecurity firm Sophos, acknowledged: "When anything like this happens, the concern that it's a cyber incident is understandable. AWS has a far-reaching and intricate footprint, so any issue can cause a major upset". However, all evidence points to a technical failure rather than malicious intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned and Moving Forward
&lt;/h2&gt;

&lt;p&gt;This incident raises critical questions about internet infrastructure resilience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Points of Failure:&lt;/strong&gt; The concentration of so many services on a single cloud provider creates systemic risk. When AWS goes down, significant portions of the internet follow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redundancy vs. Cost:&lt;/strong&gt; While AWS and other cloud providers generally maintain robust systems, the complexity of these networks means that unforeseen interactions can cause cascading failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transparency:&lt;/strong&gt; AWS customers were unable to report the problem because its automated support ticketing system was also offline, highlighting how even reporting mechanisms can be caught in the same failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Geographic Concentration:&lt;/strong&gt; Many outages appeared to be concentrated in the United States, with a focus in Virginia, which is considered the global capital for data centres, demonstrating the risks of geographic concentration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Aftermath
&lt;/h2&gt;

&lt;p&gt;As of late Monday afternoon, AWS continued working toward full resolution, with most services gradually returning to normal operation. However, the incident serves as a stark reminder of how dependent modern life has become on cloud infrastructure.&lt;/p&gt;

&lt;p&gt;Charlotte Wilson recommended that people keep good backups, save important information offline, and know alternative ways to connect to the internet or pay if systems fail — practical advice for an increasingly cloud-dependent world.&lt;/p&gt;

&lt;p&gt;The AWS outage of October 2025 will likely be studied for years to come as a case study in infrastructure fragility, centralization risk, and the need for more resilient digital systems. As we continue to move more of our lives online, building redundancy and diversification into our digital infrastructure isn't just good engineering — it's essential for maintaining the connectivity that modern society depends upon.&lt;/p&gt;

&lt;p&gt;For now, the internet has largely recovered, but the question remains: how do we build a more resilient digital future that doesn't collapse when a single provider stumbles?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is a developing story. AWS continues to monitor services and work toward complete restoration of all affected systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>shutoff</category>
    </item>
    <item>
      <title>What Two Years of Bootstrapping an AI Startup in India Taught Us</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Mon, 18 Aug 2025 08:20:00 +0000</pubDate>
      <link>https://dev.to/1geek/what-two-years-of-bootstrapping-an-ai-startup-in-india-taught-us-3h2j</link>
      <guid>https://dev.to/1geek/what-two-years-of-bootstrapping-an-ai-startup-in-india-taught-us-3h2j</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%2F5fr3fy9lo70twbapz3k8.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%2F5fr3fy9lo70twbapz3k8.png" alt="Back in 2023 it was just us (Rohit and Sahil) starting." width="708" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we started in 2023, our mission was simple: help businesses build with AI.&lt;/p&gt;

&lt;p&gt;Our first product was a fine-tuning tool for businesses to customise AI models. At the time, fine-tuning was resource-heavy &amp;amp; challenging.&lt;/p&gt;

&lt;p&gt;Fine-tuning required preparing datasets (and even synthetic data generation was not as highly feasible as today), running heavy compute, and testing multiple iterations to avoid issues like overfitting or underfitting. In practice, this meant months of work and high costs—something only big tech firms could manage.&lt;/p&gt;

&lt;p&gt;We saw this gap. Instead of making everyone rebuild models, we introduced advanced RAG-based AI chatbots that could train on a company’s own data while using existing models. RAG allowed companies to use powerful existing models while still grounding answers in their own data—giving them customisation without the cost of fine-tuning*&lt;em&gt;.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;As we worked with more customers it became clear that most businesses did not want multiple tools. They wanted one solution that could handle conversations, support teams, help them grow, and actually grow with them.&lt;/p&gt;

&lt;p&gt;We realised many teams face the same challenge: managing multiple disconnected systems slows them down. We combined our fine-tuning capabilities with the YourGPT Chatbot for enterprise users who still need customised models, while also building a single platform for conversations, training, and automation so teams no longer have to juggle separate tools.&lt;/p&gt;

&lt;p&gt;We are a small, fast-moving team bootstrapped from day one. We learn by shipping, watching, and listening. Over time every feature we built, from the action-oriented Copilots builder to AI Agents to AI Studio, Helpdesk, Voice Agents was brought together in one product: &lt;a href="https://yourgpt.ai/" rel="noopener noreferrer"&gt;YourGPT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s been a pleasure building our product from Mohali, India.&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%2Fw6p5wqkb5jrngoza00ez.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%2Fw6p5wqkb5jrngoza00ez.png" alt="Mohali, where our story&amp;nbsp;began" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a lean, customer-focused team, we help businesses unlock value and maximize innovation. One big lesson: hire for mindset. India has incredible talent, and we now prioritize curiosity, passion, and ownership over resumes—skills can be taught, but hunger to solve problems can’t.&lt;/p&gt;

&lt;p&gt;We also learned that partnerships matter as much as technology. As developers we love to build, but growing a business is more than code. Relationships with customers, vendors, and other startups help keep the momentum going. If someone has ideas or wants to discuss potential collaborations, they can reach us at &lt;a href="mailto:pr@yourgpt.ai"&gt;pr@yourgpt.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For other bootstrapped builders, here is one thing I wish I had known earlier, and I am sharing it in case it helps you too:Focus on one strong product. Do not get distracted by vibe coding, which will scatter your efforts across too many directions. Grow one vertical well and then expand it horizontally. This creates more value for your users and makes your product journey clearer.&lt;/p&gt;

&lt;p&gt;Two years in, our focus is clear: help businesses automate support, sales, and operations, and scale with AI.&lt;/p&gt;

&lt;p&gt;Real progress comes from building, shipping, and learning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bootstrapping taught us this: momentum matters more than money. Keep building.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These are lessons we continue to learn every day. If you are building something now, what is the one challenge slowing you down the most?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>startup</category>
      <category>rag</category>
    </item>
    <item>
      <title>Elevenlabs text to speech unity</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Thu, 01 Aug 2024 13:49:06 +0000</pubDate>
      <link>https://dev.to/1geek/elevenlabs-text-to-speech-unity-1jj3</link>
      <guid>https://dev.to/1geek/elevenlabs-text-to-speech-unity-1jj3</guid>
      <description>&lt;p&gt;Get Voice ID&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Net.Http;
using System.Threading.Tasks;
using UnityEngine;
using Newtonsoft.Json.Linq; // Make sure you add the Newtonsoft.Json package via Unity Package Manager

public class VoiceFetcher : MonoBehaviour
{
    private const string XiApiKey = "&amp;lt;xi-api-key&amp;gt;"; // Your API key

    // URL for the API endpoint
    private static readonly string Url = "https://api.elevenlabs.io/v1/voices";

    // Start is called before the first frame update
    private async void Start()
    {
        await FetchAndPrintVoices();
    }

    private static async Task FetchAndPrintVoices()
    {
        using (var client = new HttpClient())
        {
            // Set up headers for the API request, including the API key for authentication
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("xi-api-key", XiApiKey);
            client.DefaultRequestHeaders.Add("Content-Type", "application/json");

            try
            {
                // Send GET request to the API endpoint
                var response = await client.GetAsync(Url);

                // Check if the request was successful
                if (response.IsSuccessStatusCode)
                {
                    // Read and parse the JSON response
                    var jsonResponse = await response.Content.ReadAsStringAsync();
                    var data = JObject.Parse(jsonResponse);

                    // Loop through each voice and print the name and voice_id
                    foreach (var voice in data["voices"])
                    {
                        string name = voice["name"].ToString();
                        string voiceId = voice["voice_id"].ToString();
                        Debug.Log($"{name}; {voiceId}");
                    }
                }
                else
                {
                    // Print error message if the request was not successful
                    Debug.LogError($"Error fetching voices: {await response.Content.ReadAsStringAsync()}");
                }
            }
            catch (Exception e)
            {
                // Print any exceptions that occur
                Debug.LogError($"Exception occurred: {e.Message}");
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Text to speech&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using UnityEngine;

public class TextToSpeech : MonoBehaviour
{
    // Constants for the script
    private const int ChunkSize = 1024; // Size of chunks to read/write at a time
    private const string XiApiKey = "&amp;lt;xi-api-key&amp;gt;"; // Your API key for authentication
    private const string VoiceId = "&amp;lt;voice-id&amp;gt;"; // ID of the voice model to use
    private const string TextToSpeak = "&amp;lt;text&amp;gt;"; // Text you want to convert to speech
    private const string OutputPath = "output.mp3"; // Path to save the output audio file

    // URL for the Text-to-Speech API request
    private static readonly string TtsUrl = $"https://api.elevenlabs.io/v1/text-to-speech/{VoiceId}/stream";

    // Start is called before the first frame update
    private async void Start()
    {
        await FetchAndSaveAudio();
    }

    private static async Task FetchAndSaveAudio()
    {
        using (var client = new HttpClient())
        {
            // Set up headers for the API request, including the API key for authentication
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("xi-api-key", XiApiKey);

            // Set up the data payload for the API request, including the text and voice settings
            var data = new
            {
                text = TextToSpeak,
                model_id = "eleven_multilingual_v2",
                voice_settings = new
                {
                    stability = 0.5,
                    similarity_boost = 0.8,
                    style = 0.0,
                    use_speaker_boost = true
                }
            };

            // Serialize the data payload to JSON
            var content = new StringContent(JsonUtility.ToJson(data), System.Text.Encoding.UTF8, "application/json");

            // Make the POST request to the TTS API with headers and data, enabling streaming response
            using (var response = await client.PostAsync(TtsUrl, content, HttpCompletionOption.ResponseHeadersRead))
            {
                if (response.IsSuccessStatusCode)
                {
                    // Open the output file in write-binary mode
                    using (var fileStream = new FileStream(OutputPath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        // Read the response in chunks and write to the file
                        using (var responseStream = await response.Content.ReadAsStreamAsync())
                        {
                            var buffer = new byte[ChunkSize];
                            int bytesRead;
                            while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) &amp;gt; 0)
                            {
                                fileStream.Write(buffer, 0, bytesRead);
                            }
                        }
                    }
                    // Inform the user of success
                    Debug.Log("Audio stream saved successfully.");
                }
                else
                {
                    // Print the error message if the request was not successful
                    Debug.LogError(await response.Content.ReadAsStringAsync());
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a affiliate link, if you like you can contribute for free &lt;a href="https://try.elevenlabs.io/7okdawkpiqom" rel="noopener noreferrer"&gt;https://try.elevenlabs.io/7okdawkpiqom&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want you can sponsor our writing partners:&lt;br&gt;
&lt;a href="https://buymeacoffee.com/clubwritter" rel="noopener noreferrer"&gt;https://buymeacoffee.com/clubwritter&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Discord AI Bot with Cohere LLM Integration</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Sat, 27 Jul 2024 14:21:54 +0000</pubDate>
      <link>https://dev.to/1geek/discord-ai-bot-with-cohere-llm-integration-mgi</link>
      <guid>https://dev.to/1geek/discord-ai-bot-with-cohere-llm-integration-mgi</guid>
      <description>&lt;p&gt;Hey everyone,&lt;/p&gt;

&lt;p&gt;A few months ago, I worked on a Discord bot that uses the Cohere API. I’m now happy to share the source code with you all.&lt;/p&gt;

&lt;p&gt;The bot responds to commands and mentions in a Discord server, and it interacts with the Cohere API to generate responses. If you're looking to build a similar bot or just want to see how it’s done, you can check out the code below.&lt;/p&gt;

&lt;p&gt;Feel free to use it as a base for your own projects or to learn how to integrate Discord with an LLM. Click below image to download the code 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/himanshuskyrockets/discord-ai" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiso00lnkrnvjdvz3t30t.png" alt="Discord AI" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Github has been Shadow banned :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Replace &lt;code&gt;your-cohere-api-key&lt;/code&gt; and &lt;code&gt;your-discord-bot-token&lt;/code&gt; with your actual API key and bot token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMjltY2s2NWt2bXY4b2FqM2N1MXJkcXM1dnlpMXJwbmdpMWkzZWp3ZiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/bGgsc5mWoryfgKBx1u/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMjltY2s2NWt2bXY4b2FqM2N1MXJkcXM1dnlpMXJwbmdpMWkzZWp3ZiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/bGgsc5mWoryfgKBx1u/giphy.gif" alt="gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will Update this Blog soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What More You Can Add:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Emoji Reactions Based on Message Classification:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Feature&lt;/strong&gt;: Add functionality to react with emojis based on the sentiment or content classification of the user’s message.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom Command Handling:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Feature&lt;/strong&gt;: Allow users to define custom commands and responses in the Discord server.&lt;/p&gt;

&lt;p&gt;Hope you find it useful! If you do,You can consider supportting author on &lt;a href="https://www.patreon.com/supermanspace" rel="noopener noreferrer"&gt;Patreon 🎉&lt;/a&gt;  and &lt;a href="https://ko-fi.com/supermanspace" rel="noopener noreferrer"&gt;Ko-fi ☕&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Drop your comments down, that will motivate us to share more personal projects.&lt;/p&gt;

</description>
      <category>discord</category>
      <category>ai</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>GPT4omnini mini is Now Publicly available</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Thu, 18 Jul 2024 18:13:03 +0000</pubDate>
      <link>https://dev.to/1geek/gpt4omnini-mini-is-now-publicly-available-4g23</link>
      <guid>https://dev.to/1geek/gpt4omnini-mini-is-now-publicly-available-4g23</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuy599piuuy12eqxrq24.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuy599piuuy12eqxrq24.jpg" alt="Image description" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is 60% cheaper and better than GPT 3.5 turbo😏.&lt;/p&gt;

&lt;p&gt;What you are building with it? &lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>openai</category>
    </item>
    <item>
      <title>Create Folder Structure using LLM</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Sun, 14 Jul 2024 12:29:00 +0000</pubDate>
      <link>https://dev.to/1geek/create-folder-structure-using-llm-kg4</link>
      <guid>https://dev.to/1geek/create-folder-structure-using-llm-kg4</guid>
      <description>&lt;p&gt;I wanted to share an update on a project I worked on some time ago. I've made some changes to the code for creating project structures using LLM. Here’s the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import os
import cohere

# Initialize the Cohere client with a more secure approach
co = cohere.Client(api_key='YOUR_COHERE_KEY')

def create_project_structure(structure, base_path="/content/"):
    """
    Create a directory and file structure based on a nested dictionary.
    """
    try:
        for folder, files in structure.items():
            folder_path = os.path.join(base_path, folder)
            os.makedirs(folder_path, exist_ok=True)
            for file_name, content in files.items():
                file_path = os.path.join(folder_path, file_name)
                if isinstance(content, dict):
                    create_project_structure(content, base_path=folder_path)
                else:
                    with open(file_path, "w") as file:
                        file.write(content)
        return "Project structure created successfully."
    except Exception as e:
        return f"An error occurred: {str(e)}"

# JSON schema for the function argument
tools = [{
    "name": "create_project_structure",
    "description": "Create an entire project structure with specified files and contents.",
    "parameter_definitions": {
        "structure": {
            "description": "Dictionary specifying folders and files with their contents.",
            "type": "dict",
            "required": True
        },
        "base_path": {
            "description": "Base path where the project structure will be created.",
            "type": "str",
            "required": False
        }
    }
}]

functions_map = {
    'create_project_structure': create_project_structure
}

# Placeholder for example user request and handling
message = "write complete flappy bird game using unity"
preamble = """
## Task &amp;amp; Context
Answer questions and handle requests on a variety of topics using appropriate tools and research methods.

## Style Guide
Respond in full sentences, using proper grammar and spelling, unless requested otherwise.
"""

# Simulate handling a user request
response = co.chat(
    message=message,
    tools=tools,
    preamble=preamble,
    model="command-r",
    force_single_step=True
)

# Process and execute the recommended tool calls
tool_results = []
for tool_call in response.tool_calls:
    output = functions_map[tool_call.name](**tool_call.parameters)
    tool_result = {
        "name": tool_call.name,
        "parameters": tool_call.parameters,
        "outputs": [output],
        "call": tool_call
    }
    tool_results.append(tool_result)

print("\nTool execution results:\n")
print(json.dumps(tool_results, indent=4))

# Handle the final response using the results from tool calls
final_response = co.chat(
    message=message,
    tools=tools,
    tool_results=tool_results,
    preamble=preamble,
    model="command-r",
    temperature=0.3,
    force_single_step=True
)

print("Final answer:")
print(final_response.text)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tweak it for your needs and best of luck 🤞 &lt;/p&gt;

&lt;p&gt;If you'd like to support my work, consider checking out my Patreon: &lt;a href="https://www.patreon.com/supermanspace" rel="noopener noreferrer"&gt;Superman Space&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>codereview</category>
      <category>learning</category>
    </item>
    <item>
      <title>Emailing Hacks you might want to know - 🥶 Cold Marketing</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Sat, 13 Jul 2024 19:45:34 +0000</pubDate>
      <link>https://dev.to/1geek/emailing-hacks-you-might-want-to-know-cold-marketing-4fdl</link>
      <guid>https://dev.to/1geek/emailing-hacks-you-might-want-to-know-cold-marketing-4fdl</guid>
      <description>&lt;p&gt;As developers, we often find ourselves needing to reach out to potential clients, collaborators.&lt;/p&gt;

&lt;p&gt;Cold emailing can be a powerful tool to achieve this, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do you use other methods besides cold marketing? If so, share them in the comments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it requires a strategic approach. Here are some key takeaways from my experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Personalize Your Emails&lt;/strong&gt;: It’s not enough to just use someone’s name. Dig into their work and mention specific details. This shows you’ve done your homework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be Concise and Clear&lt;/strong&gt;: People don’t have time for long emails. Get to the point quickly and clearly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strong Subject Lines&lt;/strong&gt;: You think questions and numbers in subject lines grab attention? &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Effective Follow-Ups&lt;/strong&gt;: Don’t just send one email and hope. Follow up strategically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use a Clear Call-to-Action&lt;/strong&gt;:&lt;br&gt;
This could be a request for a meeting or a proposal. Make it easy for the recipient to respond.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Timing&lt;/strong&gt;:&lt;br&gt;
Right time deliveribility make it more likely to get more acknowledgement.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These tweaks can make a big difference in response rates. For a complete guide, check &lt;a href="https://shorturl.at/VPOmZ" rel="noopener noreferrer"&gt;post i wrote for Clubwritter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>emailing</category>
      <category>marketing</category>
      <category>hacks</category>
    </item>
    <item>
      <title>OpenAI's launch TakeAway</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Tue, 14 May 2024 09:26:52 +0000</pubDate>
      <link>https://dev.to/1geek/openais-launch-takeaway-4mle</link>
      <guid>https://dev.to/1geek/openais-launch-takeaway-4mle</guid>
      <description>&lt;p&gt;OpenAI has launched GPT-4o, an advancement in AI technology. Here’s quick highlight you need to know:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key Features:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5idt5tliabvh71d3wwxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5idt5tliabvh71d3wwxl.png" alt="Eval Score" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Image shows the Benchmark Score&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multimodal Capabilities&lt;/strong&gt;: GPT-4o can understand and generate responses across audio, vision, and text. O stands for omni.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Reasoning&lt;/strong&gt;: Offers improved real-time reasoning for diverse applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Interactivity&lt;/strong&gt;: Enhances user interaction with more natural and dynamic conversations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Launch Highlights:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Announced in May 2024 as part of OpenAI's Spring Update.&lt;/li&gt;
&lt;li&gt;Free tools and capabilities are now available for ChatGPT users.&lt;/li&gt;
&lt;li&gt;ChatGPT For Desktop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Know more about GPT-4o by visiting OpenAI’s &lt;a href="https://openai.com/index/hello-gpt-4o/"&gt;official announcement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Share your thoughts below! And excited about today's Google launch?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>YourGPT Launches Chatbot Studio: Key Takeaways</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Thu, 29 Feb 2024 16:06:17 +0000</pubDate>
      <link>https://dev.to/1geek/yourgpt-launches-chatbot-studio-key-takeaways-5e89</link>
      <guid>https://dev.to/1geek/yourgpt-launches-chatbot-studio-key-takeaways-5e89</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/V0zIjgcG6yw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today, YourGPT rolled out &lt;a href="https://yourgpt.ai/chatbot/studio"&gt;&lt;strong&gt;Chatbot Studio&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Chatbot Studio is a flow builder that allows to create advanced conversational AI agents. It includes features like detecting message intents to guide interactions, making calls to third-party APIs, responding interactively with elements such as images, carousels, and buttons, allowing human intervention through actions, and enabling customization of conversations with JavaScript code, among other capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways from the Chatbot Studio Release:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visual Flow Editor&lt;/strong&gt;: The creation of Conversational AI Agents through a visual editor by connecting nodes, making them accessible to users without coding expertise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Interaction Tools&lt;/strong&gt;: Offers advanced features like API calls, dynamic content (carousels, cards, buttons), and intent detection for richer user interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-Time Testing and Deployment&lt;/strong&gt;: Integrated emulator for testing conversational flows in real-time, ensuring a polished user experience upon deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Advanced Customisation&lt;/strong&gt;: Supports custom JavaScript code execution for custom functionalities, serving to specific needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://yourgpt.ai/chatbot/resources"&gt;&lt;strong&gt;Pre-built Templates&lt;/strong&gt;&lt;/a&gt;: Provides a variety of industry-specific templates (e-commerce, healthcare, real estate, travel, banking) for a quick and efficient setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which features do you like the most? Share them in Comments! &lt;/p&gt;

</description>
      <category>chatbotstudio</category>
      <category>yourgpt</category>
      <category>conversationalai</category>
      <category>development</category>
    </item>
    <item>
      <title>What do you want Me to Cover</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Tue, 16 Jan 2024 18:24:51 +0000</pubDate>
      <link>https://dev.to/1geek/what-do-you-want-me-to-cover-37pk</link>
      <guid>https://dev.to/1geek/what-do-you-want-me-to-cover-37pk</guid>
      <description>&lt;p&gt;Tell me in below comments that what should I cover and share with you About AI, Prompting, Programming, side Hustle or Game Development.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hows Yours Weekends 😁</title>
      <dc:creator>SupermanSpace</dc:creator>
      <pubDate>Sun, 14 Jan 2024 16:40:07 +0000</pubDate>
      <link>https://dev.to/1geek/hows-yours-weekends-2p0c</link>
      <guid>https://dev.to/1geek/hows-yours-weekends-2p0c</guid>
      <description>&lt;p&gt;Hi 👋, This post is little casual how's your weekends?&lt;/p&gt;

&lt;p&gt;Mine is quick and Short weekend, huh? 😁 Getting set for Monday morning – gearing up for the week?&lt;/p&gt;

&lt;h3&gt;
  
  
  How about yours ?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   Tell in comments.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ov9jRt4tz63NQwRSU/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ov9jRt4tz63NQwRSU/giphy.gif" alt="Image" width="478" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>weekends</category>
    </item>
  </channel>
</rss>
