Skip to content

adesousa/jared

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jared Logo

Jared: The AI COO

🐈 Jared is your AI personal assistant. Think of it like the COO (Chief Organisational Officer) of your life/company.

⚡️ Delivers core agent functionality in less than 3,000 lines of code.

📏 Real-time line count: 2,968 lines (run bash scripts/core_agent_lines.sh or bun run lines to verify anytime)

🧬 Agentic as a Service (AGAAS)

Jared is an opinionated AGAAS framework — a ready-to-deploy AI agent that runs as a persistent service, not a one-shot chatbot.

Traditional Chatbot AGAAS (Jared)
You ask → it answers → done Always-on, always listening
Single channel Multi-channel simultaneously (Telegram + Slack + WhatsApp + ...)
Stateless or session-scoped Persistent SQLite memory across all channels
No initiative Proactive via cron scheduling
Extensions require code Drop a SKILL.md file, restart, done
Generic framework Opinionated: batteries included, decisions made

The AGAAS Philosophy

  1. Agent, not assistant. Jared doesn't wait passively — it triggers cron jobs and delivers results to the right channel proactively.
  2. Service, not CLI. Run it once, connect your channels, and Jared stays alive — handling messages from any source, remembering context across sessions.
  3. Opinionated, not configurable-to-death. SQLite for memory (not a vector DB). Markdown for skills (not a plugin SDK). Event bus for routing (not a message queue). Every choice optimizes for simplicity and low token cost.
  4. Ultra-lightweight by design. The entire agent core fits in < 3,000 LOC. If you can read JavaScript, you can understand and customize every line.

Key Features

  • 🪶 Ultra-Lightweight: Core agent logic < 3,000 lines. Just the essentials. No bloat.
  • 🏢 Multi-Project Support: Seamlessly manage and switch between multiple isolated projects, each with its own configuration, backlog, and persistent memory database.
  • 🧠 Bun SQLite Memory: Uses a robust native SQL memory system with bun:sqlite to manage Short-Term Context, Categorized Long-Term Memory (Facts, Preferences, Rules, Summaries), and Cherry-Pick Grep (search) capabilities.
  • 📉 Native Token-Reduction Strategy: Drastically reduces token consumption through intelligent context management and selective memory retrieval.
  • 🗺️ Universal Routing: Jared automatically handles OpenAI-compatible endpoints (Ollama, vLLM, OpenRouter) and applies native adapter patterns for providers with custom schemas (like Google Gemini).
  • 🤖 Agent Orchestrator / Dynamic Routing: Explicitly route any message to a specific provider by appending a flag (e.g., --openai, --gemini, --ollama) to seamlessly switch models mid-conversation.
  • 🔌 MCP Support: First-class Node.js implementation of Model Context Protocol for seamless tool extraction from stdio/SSE servers.
  • 🌐 Web Search & Fetch: Built-in Brave Search integration and URL content extraction — no external dependencies.
  • 🎯 Markdown Skills: Dynamic skill system inspired by Nanobot/OpenClaw — extend Jared by dropping a SKILL.md file into src/skills/.
  • 🔒 Exec Guard: Three-layer security for shell commands — allowlist, blocklist, and user confirmation mode.
  • 🏗️ Workspace Sandboxing: Restrict agent operations to a dedicated workspace directory with path traversal protection.

💬 Supported Channels

Channel What you need
Terminal Console Nothing — works out of the box
Telegram Bot token from @BotFather
Discord Bot token + Message Content intent
Slack Bot token (xoxb-...) + App-Level token (xapp-...)
WhatsApp QR code scan
Telegram

1. Create a bot

  • Open Telegram, search @BotFather
  • Send /newbot, follow prompts
  • Copy the token

2. Configure

{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "YOUR_BOT_TOKEN"
    }
  }
}

3. Run

jared start <project-name>
Discord

1. Create a bot

2. Enable intents

  • In the Bot settings, enable MESSAGE CONTENT INTENT

3. Configure

{
  "channels": {
    "discord": {
      "enabled": true,
      "token": "YOUR_BOT_TOKEN"
    }
  }
}

4. Invite the bot

  • OAuth2 → URL Generator
  • Scopes: bot
  • Bot Permissions: Send Messages, Read Message History
  • Open the generated invite URL and add the bot to your server

5. Run

jared start <project-name>
Slack

Uses Socket Mode — no public URL required.

1. Create a Slack app

  • Go to Slack APICreate New App → "From scratch"

2. Configure the app

  • Socket Mode: Toggle ON → Generate an App-Level Token with connections:write scope → copy it (xapp-...)
  • OAuth & Permissions: Add bot scopes: chat:write, reactions:write, app_mentions:read
  • Event Subscriptions: Toggle ON → Subscribe to bot events: message.im, message.channels, app_mention
  • App Home: Enable Messages Tab
  • Install App: Click Install to Workspace → copy the Bot Token (xoxb-...)

3. Configure

{
  "channels": {
    "slack": {
      "enabled": true,
      "botToken": "xoxb-...",
      "appToken": "xapp-..."
    }
  }
}

4. Run

jared start <project-name>
WhatsApp

Requires Node.js ≥18.

1. Configure

{
  "channels": {
    "whatsapp": {
      "enabled": true
    }
  }
}

2. Run and scan the QR code with WhatsApp → Settings → Linked Devices

jared start <project-name>

📦 Installation & Setup

We recommend using Bun (primary) or npm (secondary).

  1. Clone and install dependencies:
git clone adesousa/jared.git
cd jared
bun install
bun link
  1. Initialize
jared onboard <project-name>
  1. Configure (.jared/<project-name>/config.json)

Add or merge these parts into your config (other options have defaults).

Providers

Define your backend API endpoints and keys:

{
  "providers": {
    "ollama": {
      "url": "http://localhost:11434/v1",
      "keys": [
        {
          "name": "ollama-key",
          "value": "ollama",
          "models": ["qwen3:4b-instruct", "glm-4.6:cloud"]
        }
      ]
    },
    "openai": {
      "url": "https://api.openai.com/v1",
      "keys": [
        {
          "name": "openai-key",
          "value": "sk-...",
          "models": ["chatGPT-4o"]
        }
      ]
    },
    "gemini": {
      "keys": [
        {
          "name": "gemini-key",
          "value": "AIzaSy...",
          "models": ["gemini-2.0-flash"]
        }
      ]
    }
  }
}
Provider Purpose Get API Key
ollama LLM (local, OpenAI-compatible)
openai LLM (GPT direct) platform.openai.com
gemini LLM (Gemini direct, native adapter) aistudio.google.com
mistral LLM (Mistral direct) console.mistral.ai
openrouter LLM (access to all models via single API) openrouter.ai

Any OpenAI-compatible endpoint also works (vLLM, LM Studio, etc.) — just set the url field.

Default Model

Set your default provider and active model:

{
  "agents": {
    "defaults": {
      "provider": "ollama",
      "model": "glm-4.6:cloud",
      "thinking": false,
      "maxIterations": 15,
      "systemPromptInterval": 5
    }
  }
}
Field Description Default
provider The default LLM provider to use ollama
thinking Enable reasoning <think> blocks true
model The active model for the provider glm-4.6:cloud
maxIterations Max tool-use loops per message (prevents infinite loops/runaway $) 15
systemPromptInterval How often to re-inject the full system prompt during a multi-step task (see Token Optimization) 5

Explicit Model Routing

You can explicitly ask Jared to process a specific message using a different provider than the default one by appending a flag to your message (e.g., --mistral, --ollama, --openai).

When you use a flag, Jared will override the default configuration for that specific interaction and route your prompt to the requested provider.

Example usage:

  • translate this text in french --mistral
  • write a complex python script --openai
  • what is the weather like? --ollama

Configuration: To specify which model should be called when using a provider's flag, add a default key to the provider's configuration in .jared/<project-name>/config.json. If no default is specified, it will fall back to the first model in the models array.

{
  "providers": {
    "ollama": {
      "url": "http://localhost:11434/v1",
      "keys": [
        {
          "name": "ollama-key",
          "value": "ollama",
          "default": "qwen3.5:4b-nvfp4",
          "models": ["qwen3.5:4b-nvfp4", "glm-4.6:cloud"]
        }
      ]
    }
  }
}

Channels

Enable and configure any channels you want Jared to run on:

{
  "channels": {
    "console": { "enabled": true },
    "discord": { "enabled": true, "token": "your-bot-token" }
  }
}

Security

Configure security for the exec tool (shell command execution):

{
  "security": {
    "exec": {
      "mode": "confirm",
      "allowedBins": [
        "curl",
        "gh",
        "summarize",
        "grep",
        "cat",
        "git",
        "node",
        "bun",
        "..."
      ]
    }
  }
}
Mode Behavior
confirm Allowlist + Blocklist + Ask user approval for every command (default)
allowlist Allowlist + Blocklist only (no prompt)
unrestricted Blocklist only (dangerous patterns always blocked)

Configure workspace sandboxing to restrict all exec commands to a dedicated directory:

{
  "security": {
    "restrictToWorkspace": true,
    "workspaceDir": ".jared/<project-name>/workspace"
  }
}

When enabled, commands cannot access files outside the workspace (blocks ../ traversal and absolute paths). See SECURITY.md for details.

See SECURITY.md for full details.

Web Search (Brave)

Optionally configure Brave Search for the web_search tool:

{
  "tools": {
    "web": {
      "search": {
        "apiKey": "your-brave-api-key"
      }
    }
  }
}

Get a free API key at brave.com/search/api.

Token Optimization

Jared's agent loop uses a sparse system prompt strategy to reduce token consumption on multi-step tasks.

When a task requires multiple tool calls (e.g., searching the web, reading files, running commands), the agent calls the LLM multiple times in a loop. Without optimization, every call re-sends the full system prompt — soul, skills list, tool instructions, core memory — on every single iteration. This gets expensive fast.

How it works:

  • Iteration 0: Full system prompt sent (soul, tools, skills, core memory, team context)
  • Iterations 1–N: A slim stub ("Continue the task based on the conversation so far.") is sent instead
  • Every systemPromptInterval iterations: The full system prompt is re-injected to refresh the model's persona and rules

For a task with 10 tool calls and systemPromptInterval: 5, the full system prompt is only sent twice (iterations 0 and 5) instead of 10 times — roughly 80–90% fewer system prompt tokens for complex agentic tasks.

{
  "agents": {
    "defaults": {
      "systemPromptInterval": 5
    }
  }
}
Value Behavior
1 Full system prompt on every iteration (original behavior, maximum safety)
5 Full prompt on iterations 0, 5, 10, ... (default — good balance)
99 Full prompt only on iteration 0, never refreshed (maximum savings, best for short focused tasks)

When debug: true is set, Jared logs [Loop] Re-injecting full system prompt at iteration N so you can observe the behavior.

Debug

Enable verbose debug logging:

{
  "debug": true
}

When false (default), debug-level logs are silently discarded.

MCP (Model Context Protocol)

The config format is compatible with Claude Desktop / Cursor. You can copy MCP server configs directly from any MCP server's README.

Jared supports MCP — connect external tool servers and use them as native agent tools.

{
  "mcp": {
    "servers": {
      "filesystem": {
        "command": "npx",
        "args": [
          "-y",
          "@modelcontextprotocol/server-filesystem",
          "/path/to/dir"
        ]
      },
      "my-remote-mcp": {
        "type": "url",
        "url": "https://example.com/mcp/sse",
        "headers": {
          "Authorization": "Bearer xxxxx"
        }
      },
      "my-streamable-mcp": {
        "type": "url",
        "transport": "streamable",
        "url": "https://example.com/mcp",
        "enabled": false
      }
    }
  }
}
Mode Config Example
Stdio command + args Local process via npx / uvx
HTTP/SSE type: "url" + url + headers (optional) Remote endpoint
Streamable HTTP type: "url" + transport: "streamable" + url Modern remote endpoint

Pro-Tip: You can add "enabled": false to any MCP server configuration to temporarily disable it and prevent its tools from injecting into Jared's context, without having to delete the config entirely.

MCP tools are automatically discovered and registered on startup. The LLM can use them alongside built-in tools — no extra configuration needed.

  1. Start Jared and Chat:
jared start <project-name>

🛠️ Native Tools

Jared ships with these built-in tools (no configuration needed):

Tool Description
exec Execute shell commands (secured by Exec Guard)
search_memory Search past conversation history by keyword
add_memory Save a long-term memory (fact, preference, rule, summary)
remove_memory Remove an outdated memory by ID
cron Schedule reminders and recurring tasks (add/list/remove, cron expressions, timezones)
message Send proactive messages to the user on any channel
spawn Spawn a background subagent for async tasks (supports configurable roles via src/team/)
web_search Search the web via Brave Search API
web_fetch Fetch and extract readable text from any URL
read_skill_manual Read the full markdown instructions from a skill so the agent knows how to use it

🧑‍💻 The team/ Folder (Subagent Roles)

When using the spawn tool to trigger background tasks, Jared typically adopts its default personality. However, for specialized tasks, you can add Markdown files to the src/team/ folder (e.g., web_developer.md, data_analyst.md). If the spawn tool is called with a specific role parameter, the background subagent will assume that specialized system prompt instead.

Dynamic Awareness: Jared automatically detects files in the src/team/ directory and injects their names into his system prompt. This gives him dynamic awareness of all available team members so he can proactively assign tasks to them without overloading context.

🎯 Skills

Jared uses a Markdown-based skill system inspired by the Nanobot/OpenClaw architecture. Skills are SKILL.md files with YAML frontmatter. To keep context extremely lightweight, only the name and description of each skill are loaded into the main agent prompt. If Jared needs to use a skill, he uses the read_skill_manual tool to dynamically load the exact instructions for that turn.

Built-in Skills

Skill Description
cron Schedule reminders and recurring tasks
memory Two-layer memory system with grep-based recall
github Interact with GitHub using the gh CLI
weather Get weather info (no API key required)
summarize Summarize URLs, files, and YouTube videos
skill-creator Create new skills

Adding a New Skill

  1. Create a folder in src/skills/ (e.g., src/skills/my-skill/)
  2. Add a SKILL.md with YAML frontmatter and instructions:
---
name: my-skill
description: What this skill does and when to use it.
---

# My Skill

Instructions for the agent on how to use this skill...
  1. Restart Jared — the skill is automatically loaded!

⏰ Scheduling & Backlog

Jared uses .jared/<project-name>/BACKLOG.md as the single source of truth for both scheduled tasks (Cron) and the Product Backlog. Every 60 seconds, Jared automatically synchronizes his internal scheduler with this file. If you edit it manually, Jared will instantly load the new schedule!

# Project Backlog

## One Shot Tasks

### 📅 2026-05-04 10:00 — Call Client

- Discuss the new deliverables

## Daily Tasks

### ⏰ 09:00 — Morning Briefing

- Summarize schedule and upcoming tasks

## Weekly Tasks

### ⏰ Friday 17:00 — Weekly Report

- Generate the weekly wrap-up report

## Monthly Tasks

### ⏰ 25th 10:00 — Billing Review

- Check API usage and billing

## Product Backlog

- [ ] Add the new feature

The agent uses the cron tool to manage these tasks seamlessly. One Shot Tasks are automatically removed from the file after they are executed. You can simply ask Jared: "Remind me to call John on Friday at 5pm" and he will add it to the file.

CLI Reference

Command Description
jared onboard <project> Initialize the agent and generate .jared/<project>/config.json
jared start <project> Start Jared in interactive mode and connect configured channels
jared lines Check real-time codebase size (ensuring it stays under 3,000 LOC)
jared reset-memory <project> Completely wipe the project's persistent memory database
jared stats <project> Show core token usage stats for a project
jared audit Run dependency security audit (checks for known vulnerabilities)

Interactive mode exits: exit, quit, or Ctrl+D.

🚀 Roadmap

We are building Jared to be the ultimate ubiquitous AI partner. Here’s what’s coming next, focused on delivering maximum value to your daily workflow:

  1. Self-Improving Intelligence (Closed Loop): Implementing a continuous feedback system where Jared analyzes his own performance to refine skills, optimize tool calls, and improve memory rules—complete with configurable token budget management.
  2. Expanded Capability Library: A massive expansion of the built-in SKILL.md collection to handle everything from advanced data analysis to deep research and creative workflows.
  3. Natural Voice Interaction: A dedicated voice mode for fluid, hands-free communication across mobile and desktop.
  4. Jared Web Channel: A sleek web interface (web.js) featuring a multi-pane dashboard:
    • Left: Project Switcher
    • Right (Tabs): Live Conversation, Backlog, and Voice mode.
  5. Ambient Home Intelligence: Integration with WiFi speakers and smart home ecosystems, transforming Jared into a proactive physical home assistant.
  6. Ubiquitous Visual Intelligence: Connecting with wearable tech (like Ray-Ban Meta glasses) to provide real-time assistance based on what you see.
  7. Mobile-First Presence: Native Android integration and Pixel Watch support with "Hey Jared" wake-word triggers for true on-the-go productivity.

🏗️ Architecture Details

Jared utilizes a generalized event bus natively (EventEmitter) to bridge decoupled channel connectors (Slack, Telegram, etc.) with the core agent loop. Core configurations are mapped in config.json. The engine seamlessly parses incoming instructions, integrates facts via the native SQLite memory tools, executes tools (via direct JS skills or MCP abstractions), and loops until the task is complete before responding to the source channel.

📁 Project Structure

jared/
├── .jared/
│   └── <project-name>/
│       ├── config.json     # ⚙️ Agent configuration
│       ├── memory.db       # 🧠 SQLite persistent memory
│       ├── BACKLOG.md      # ⏰ Scheduled tasks and Product Backlog
│       ├── SOUL.md         # 📜 Agent persona and guidelines
│       └── workspace/      # 🔒 Exec sandbox (when restrictToWorkspace is on)
├── src/
│   ├── agent/          # 🧠 Core agent logic
│   │   ├── agent.js    #    Agent manager (spinUp orchestrator)
│   │   ├── loop.js     #    Agent loop (LLM ↔ tool execution)
│   │   ├── context.js  #    Prompt builder
│   │   ├── memory.js   #    Native bun:sqlite persistent memory
│   │   ├── skills.js   #    Dynamic SKILL.md loader
│   │   └── exec-guard.js #  Exec security (allowlist/blocklist/confirm)
│   ├── tools/          # 🔧 Built-in tool implementations
│   │   ├── exec.js     #    Shell command execution
│   │   ├── cron.js     #    Cron job scheduling
│   │   ├── memory.js   #    Memory search/add/remove
│   │   ├── message.js  #    Proactive messaging
│   │   ├── spawn.js    #    Background subagent spawning
│   │   ├── web.js      #    Web search & fetch
│   │   └── read_skill_manual.js # Loading markdown skill context
│   ├── skills/         # 🎯 Markdown-based skills (SKILL.md)
│   │   ├── cron/       #    Reminders & scheduling
│   │   ├── memory/     #    Memory management guide
│   │   ├── github/     #    GitHub CLI integration
│   │   ├── weather/    #    Weather lookups
│   │   ├── summarize/  #    URL/file summarization
│   │   └── skill-creator/ # Skill creation guide
│   ├── bus/            # 🚌 Message routing (EventEmitter)
│   ├── channels/       # 📱 Chat channel integrations
│   ├── cli/            # 🖥️ Commands (util.parseArgs)
│   ├── config/         # ⚙️ Configuration options
│   ├── cron/           # ⏰ Scheduled tasks engine (BACKLOG.md sync)
│   ├── mcp/            # 🔌 Model Context Protocol integrations
│   ├── providers/      # 🤖 Universal LLM router
│   ├── session/        # 💬 Conversation session tracking
│   ├── identity/       # 📜 SOUL and agent guidelines
│   ├── team/           # 🧑‍💻 Specialized Subagent identities (e.g. web_developer.md)
│   └── utils/          # 🛠️ Helper utilities
├── assets/             # 🖼️ Static assets (Jared Logo)
└── scripts/            # 📜 Operations scripts (core_agent_lines.sh)

About

Your Ultra-Lightweight AI COO ! A small "OpenClaw" implementation in Javascript

Topics

Resources

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors