squadforge
v0.1.5
Published
JavaScript framework for building a main AI agent that orchestrates specialized subagents, tools, prompts, skills, sessions, and cron workflows.
Maintainers
Readme
🤖 Squadforge
Forge one main AI agent. Orchestrate the whole squad.
Squadforge is a JavaScript framework for building one main AI agent that coordinates specialized subagents, local tools, prompt files, reusable skills, persisted sessions, and cron-driven workflows.
Squadforge is designed for agent systems that need a clean filesystem convention, a long-lived runtime loop, and built-in delegation primitives without forcing application code to own the orchestration internals.
✨ Features
- Filesystem-driven app structure for agents, prompts, skills, tools, sessions, and crons
- Single
forge(...)entrypoint for booting a runtime-backed leader agent - Built-in leader and subagent communication primitives
- Background subagent registry with follow-up chat support
- Persistent session storage with trimming and TTL cleanup
- Runtime-owned cron scheduling with queueing into agent sessions
- OpenRouter-backed LLM client included out of the box
- Channel-agnostic inbound and outbound runtime message contract
📦 Install
npm install squadforgeRequirements:
- Node.js 18 or newer
🚀 Quick Start
import { forge, OpenRouterLlm } from 'squadforge';
const agent = await forge({
rootDir: process.cwd(),
llm: new OpenRouterLlm({
apiKey: process.env.OPENROUTER_API_KEY
}),
model: 'openai/gpt-5-mini'
});
agent.onMessage(receiveMessage => {
telegram.on('message', update => {
receiveMessage({
sessionId: `telegram:${update.chat.id}`,
role: 'user',
content: update.text,
replyToId: update.message_id
});
});
});
agent.sendMessage(async message => {
await telegram.sendMessage(message.sessionId.split(':')[1], message.content);
});
await agent.start();🗂️ Project Layout
my-app/
agents/
leader.md
researcher.md
coder.md
prompts/
SUBAGENTS.md
TOOLS.md
SKILLS.md
SUBAGENT.md
skills/
research-report/
SKILL.md
tools/
web/
web_search.js
filesystem/
read_file.js
sessions/
crons/🤖 Agent Definitions
Each agent lives in agents/<id>.md.
Example:
---
name: Researcher
description: Searches the web and summarizes findings.
allowed_tools:
- web_search
model: openai/gpt-5-mini
---
You are a research specialist.Rules:
leader.mdis required- at least one non-leader subagent file is required
allowed_toolsmay list external tools; built-in tools are injected automatically by role
🧩 Prompt Composition
Squadforge uses the markdown body of each file in agents/ as the base prompt for that agent.
- Leader prompt:
agents/leader.md+prompts/SUBAGENTS.md+prompts/TOOLS.md+prompts/SKILLS.md - Subagent prompt:
prompts/SUBAGENT.md+ subagent markdown body +prompts/TOOLS.md
If the prompts/ directory or one of the supported prompt files is missing, Squadforge scaffolds the defaults automatically.
Supported placeholders inside prompt fragments:
{subagentsList}{toolsList}{skillsList}
🛠️ Built-in Tools
Leader agents automatically receive:
get_datetimeread_filesend_filesubagent_startsubagent_chatsubagent_list
Subagents automatically receive:
get_datetimeask_main_agent
Cron management tools are also available in the runtime tool catalog:
cron_createcron_getcron_listcron_updatecron_delete
🧠 Skills
Each skill lives under skills/<skill-id>/SKILL.md.
Supported frontmatter fields:
namedescription
Loaded skills are injected into prompts/SKILLS.md and are available to prompt composition.
📡 Channel Contract
Squadforge keeps channel integration outside the runtime, but the runtime speaks one normalized message shape.
Inbound messages accepted by onMessage(...):
sessionIdorsessionKey: required session identifierrole: optional, defaults tousercontent: optional text contentreplyToId: optional transport-specific reply targetmetadata: optional adapter-defined metadatafile: optional inbound file payload
Outbound messages emitted through sendMessage(...) and direct runtime sends:
sessionIdsessionKeyrolecontentreplyToIdmetadatatimedOuterrorfile
Outbound file payload shape:
pathcaptionnamemimeTypemetadata
⏱️ Runtime Policies
Default runtime behavior:
- soft runtime deadline per agent run: 5 minutes
- wrap-up warning threshold: 60 seconds remaining
- maximum messages kept per session: 50
- session TTL for non-leader sessions: 24 hours
- transient LLM retries: 2
These can be overridden through forge(...):
const agent = await forge({
maxRuntimeMs: 5 * 60 * 1000,
wrapUpThresholdMs: 60 * 1000,
maxMessagesPerSession: 50,
sessionTtlMs: 24 * 60 * 60 * 1000,
llmChatMaxRetries: 2
});The runtime checks deadlines between turns. It does not cancel in-flight LLM requests or already-running tool executions.
📚 Public API
Current exports:
forgeOpenRouterLlmloggerresolveLogFilesreadLogTail- config constants from
src/config.js
The folder loaders and most runtime internals are intentionally private.
🧪 Development
Run the example from a repository checkout:
npm run example⚖️ License
MIT
