# Gadget

An AI-fueled browser extension and web application for the next generation of social media.

## Overview

Gadget is a browser extension - and web application - that implements a chat with an AI agent named Gadget.

Gadget, by calling tools, will help the user use the web. Gadget will be able to navigate to URls either in a new tab or the current one. Gadget will be able to read the contents of a web page or snap a screenshot to view an image, etc., to help summarize the contents, help the user understand the contents, find related content, etc. Gadget will, on some sites, be able to fill out forms for the User (if they implement the Gadget interface), and assist the user with basic online tasks and automations.

This project is only at the proof-of-concept stage, and we are just getting started now. A backend microservice will be created built in TypeScript on NodeJS using ExpressJS, Socket.io, MongoDB, Qdrant (vector database) and the [ollama](https://www.npmjs.com/package/ollama) API. The front-end will POST chat messages from the sidebar browser extension, and receive streaming responses for the display to the user in the scrolling message list in the sidebar extension.

We are only concerned with supporting the Google Chromium browser, but we will be using the [Vite](https://vitejs.dev/) build tool for both projects to make them as lightweight and performant as possible. We will also use ReactJS for the front-end projects, and TailwindCSS for styling, sharing as much as possible in ./src/lib when appropriate.

## Sidebar Chat

The design of the sidebar chat component is deceptively basic at first, and by default. Complexity lives in slide-out panels. All the user sees normally is a header bar, scrolling chat message list (with styled scrollbar), and their input bar at the bottom.

The header of the sidebar is 24px in height, and will present the Gadget icon (opens gadget.gab.com in a named "\_gadget" tab). The Gadget icon is followed a basic menu of simple selections that will be square icons.

To interact with Gadget, people generally don't use a "menu" or click-style actions. They enter a chat message, ask questions, or just tell Gadget the settings they want. "Gadget, please change to dark mode," will do that. The chat message is sent to the backend, where it is passed to the Ollama `chat` API for processing and for Tool calls per the Ollama API standard. Socket.io is used to stream the response back to the sidebar widget for display in real-time. As thinking messages arrive, their content is added to the "Thinking..." region of the current turn. As response messages arrive, they are added to the Response area of the current turn.

What the user can expect Gadget to be able to do for them depends on whether they are accessing the mobile or Desktop version. The mobile version is NOT a browser extension. It is just a web page, installable as an app, that the User can open to FETCH information and have conversations with Gadget. Gadget will not, however, be able to control their browser and provide browser-based automations when being accessed from the mobile interface.

## Turns

A turn is a "block" in the scrolling chat message list, and will contain the following information:

- User's prompt (chat input text)
- LLM's thinking messages in a Thinking block (expandable/collapsable, default collapsed)
- LLM's response messages in a Response block
- Tool calls in a Tools block (collapsed by default, opens the Tool Shelf slide-out panel when selected)

Turns are the history of the chat. They are stored on the server. `/api/v1/chat/:sessionId` is their endpoint. The User will POST chat input to `/api/v1/chat/:sessionId` to send a chat message, and the response will be streamed to them over Socket.io to a channel named for the chat session ID that the User joins when connecting to that chat session.

## Sessions

The first icon after the Gadget icon in the header bar is the Sessions icon. This will toggle open the Session panel, where the User can scroll through their sessions with Gadget, and search them. These are all endpoints at and under `/api/v1/chat`.

Justified right in the header is a + plus icon, which creates a new session and immediate connects to it by POSTing to `/api/v1/chat` specifying session type of `mobile` (app), `desktop` (app), or `extension` (browser extension), to indicate which experience and set of capabilities is to be delivered to the User.

This will control the selection of separate system prompts, which are defined in `./data/prompts/gadget/system.desktop.md` and `./data/prompts/gadget/system.mobile.md` and `./data/prompts/gadget/system.extension.md`. A starter system prompt is provided in each of those files to get the project started. They are already being loaded in the AgentService when building the Agent's system prompt, merging with runtime information, etc.

The `Session` object (Mongoose Model, etc.) **is** the session context. The `ChatMessage` model will have a `session` field that references the `Session` by `Session._id`.

## Pinboard

The Pinboard is a persistent note-taking mechanism within a chat session. It allows the LLM agent (Gadget) to store and remove notes directly in the session context/system prompt, giving the model a way to edit its own context and maintain important information across turns without relying on conversation history.

### How It Works

- Pins are stored as a `pins` array on the `ChatSession` model, each with an auto-generated `_id` and `content` string
- When building the system prompt for each chat turn, all pins are appended under a `## PINBOARD` section
- The agent uses two tools to manage pins:
  - `pin_add`: Adds a new pin with text content
  - `pin_remove`: Removes a pin by its `_id`
- Total pinboard content is limited to 8192 characters across all pins. When the limit is reached, the agent must remove existing pins before adding new ones

### Why It Matters

The pinboard gives the agent agency over its own context. Instead of the agent having to re-read conversation history or repeat important information in every response, it can pin key facts — user preferences, task specifications, research findings, URLs — and have them automatically included in the system prompt for every subsequent turn. This is more efficient than writing notes in response text, keeps responses clean, and ensures critical context is always available.

### Implementation

- Model: `IChatSessionPin` subdocument schema with `_id` and `content` fields (`src/models/chat-session.ts`)
- Tools: `PinAddTool` and `PinRemoveTool` in `src/tools/storage/`
- System prompt: Pins appended in `buildAgentSystemPrompt()` in `src/services/agent.ts`
- Prompts: Pinboard section added to all three system prompts (`data/prompts/gadget/system.*.md`)

## Project Structure

Generally, the client projects will call into the backend project to receive backend data and information services such as AI inference over HTTP. The backend will usually respond quickly with an asynchronous HTTP 200 indicating, "I got your chat input." It will then create a Bull Queue job, and submit the session (which contains the User) and prompt as job data to the `gadget-chat` job queue.

A worker process will pick up the job, and perform the AI inference. The response is streamed in real-time back to the User over Socket.io, where it is added to the current turn in the chat message list in the appropriate areas of the current processing turn. Thinking messages go into the Thinking... area. Response messages append to the Response area. Tool calls (their parameters and response, errors included) are added to the Tools slide-out panel.

### Common

./src/lib - common code to be shared by all, such as database/redis connections, the Ollama API instance, etc.

### Backend

./src/models - the Mongoose TypeScript interface, schema, and model definitions/implementations
./src/services - the service layer for the application
./src/tools - Ollama API Tool definitions, and their implementations
./src/controllers - the ExpressJS controllers that implement the HTTP interface
./src/workers - the background workers that perform tasks such as AI inference, etc.

./src/web-app.ts - the main web app/backend server
./src/web-cli.ts - the command-line interface for performing low-level admin functions

### Front-End (HTML5 PWA/SPA)

./src/client - the ReactJS/Tailwind/Vite client used to build the browser application (PWA/SPA)
./src/extension - the ReactJS/Tailwind/Vite client project used to build the browser sidebar extension

These are separate projects that let us implement the separate concerns of the Desktop App and the Mobile app with better focus and results. They can share common logic and interfaces through `./src/lib`, but can then implement their own UI/UX components and make full use of the device they are running on.

#### Backend

- NodeJS
- MongoDB
- Redis
- Qdrant
- TypeScript
- ExpressJS
- Socket.io
- Ollama API
- BullMQ
- Mongoose
- tsx
- Vite
- Tailwind
- ReactJS
- Jest 26+
- SuperTest 5+
- ESLint 8+
- Prettier 2+
