AI AgentForge Documentation
AI Agent platform with multi-agent workflows, 30+ built-in tools, and a real-time web interface.
Quick Start
Get started with AI AgentForge in 3 simple steps.
Create Your Account
Click Get Started on the landing page. Sign up with your email or use Google Sign-In for one-click access.
Connect a Provider
Choose your LLM provider during onboarding:
OpenRouter (200+ models, free tier available),
OpenAI, NVIDIA NIM, Ollama (local), or vLLM (self-hosted).
Enter your API key and pick a model.
Start Chatting
Select an agent from the sidebar and type your message. Agents use tools automatically — search the web, run code, send emails, and much more.
Tips to Get the Most Out of AI AgentForge
| Feature | How to Use It |
|---|---|
| Switch Agents | Click any agent in the sidebar or type / in the chat to quickly select one. Each agent has specialized tools. |
| Run Workflows | Switch to Workflows tab in the header. Workflows chain multiple agents together for complex tasks like "Research & Email". |
| Enhance Prompts | Press Ctrl+E or click to let AI rewrite your prompt for better results. |
| Message History | Press ↑ / ↓ arrow keys in the chat input to cycle through your previous messages. |
| Tag Messages | Type # followed by a tag name (e.g., #project-x) to organize your conversations.
|
| Speech Input | Click the microphone button to dictate your message using speech-to-text. |
| View Analytics | Open the gear menu → Analytics to see your usage stats, token counts, and response times. |
| Customize Settings | Open the gear menu → Configuration to change your model, tweak agent settings, or manage workflows. |
If you choose OpenRouter as your provider, many models are available for free — including Llama, Gemma, and Mistral variants. The onboarding wizard highlights free models with a toggle.
Architecture
How the system is organized.
Project Structure
| Folder / File | Purpose |
|---|---|
config/ | JSON config files (agents, tools, workflows, email, global config) |
core/ | Core engine: orchestrator, agent, LLM provider, tool registry, storage |
tools/ | 21 tool implementations (web search, email, files, DB, charts, weather, etc.) |
static/ | Web UI frontend (HTML, CSS, JavaScript) |
data/ | Persistent storage (chat history, workspace data) |
workspace/ | Sandboxed file storage for file tools & chart outputs |
app.py | Application entry point — run this to start the server |
.env | API keys (never commit this to git!) |
LLM Providers
AI AgentForge is model-agnostic — use cloud APIs, local models, or self-hosted inference servers. All providers use the OpenAI-compatible API format.
Supported Providers
OpenRouter
Access 100+ models (Llama, Mistral, Gemini, Claude) through a single API. Free tier available. Default provider.
Ollama (Local)
Run LLMs locally on your machine. 100% private — no data leaves your server. Supports Llama 3, Mistral, Phi, Gemma, and more.
vLLM (Self-Hosted)
High-performance inference server for GPU clusters. OpenAI-compatible API. Best for production deployments with large models.
OpenAI
Direct access to GPT-4o, GPT-4o-mini, and other OpenAI models. Requires an OpenAI API key.
NVIDIA NIM
GPU-optimized cloud inference with Nemotron, Llama, and enterprise models. OpenAI-compatible API at integrate.api.nvidia.com.
Privacy Comparison
| Provider | Data Leaves Server? | Privacy Level | Best For |
|---|---|---|---|
| Ollama | No — runs locally | 100% private | Healthcare, legal, finance, regulated industries |
| vLLM | No — self-hosted | 100% private | Production GPU servers, high-throughput workloads |
| OpenRouter | Yes — cloud API | Trust-based | Quick start, free models, model variety |
| OpenAI | Yes — cloud API | Trust-based | GPT-4o access, enterprise API agreements |
| NVIDIA NIM | Yes — cloud API | Trust-based | GPU-optimized Nemotron, Llama models, enterprise workloads |
Configuration
All providers are configured in config/config.json. Add, remove, or modify providers as needed:
{
"providers": {
"openrouter": {
"api_key": "${OPENROUTER_API_KEY}",
"base_url": "https://openrouter.ai/api/v1"
},
"ollama": { // No real API key needed
"api_key": "ollama",
"base_url": "http://localhost:11434/v1"
},
"vllm": { // No real API key needed
"api_key": "not-needed",
"base_url": "http://localhost:8001/v1"
},
"nvidia": {
"api_key": "${NVIDIA_API_KEY}",
"base_url": "https://integrate.api.nvidia.com/v1"
}
}
}
Using a Provider per Agent
Each agent can use a different provider/model. Just set the model with the provider prefix:
// Cloud model via OpenRouter "model": "meta-llama/llama-3.3-70b-instruct:free" // Local model via Ollama "model": "ollama/llama3.2" // Self-hosted model via vLLM "model": "vllm/mistral-7b-instruct" // Direct OpenAI "model": "openai/gpt-4o-mini" // NVIDIA NIM cloud inference "model": "nvidia/llama-3.1-nemotron-ultra-253b-v1"
Setup Guides
Ollama Setup (5 minutes)
# 1. Install Ollama (https://ollama.com) # 2. Pull a model ollama pull llama3.2 # 3. Ollama runs automatically at http://localhost:11434 # 4. Set agent model to "ollama/llama3.2" — done!
vLLM Setup
# 1. Install vLLM (requires NVIDIA GPU) pip install vllm # 2. Start the server vllm serve mistral-7b-instruct --port 8001 # 3. Set agent model to "vllm/mistral-7b-instruct" — done!
You can use different providers per agent. For example: Research Agent on free OpenRouter models, Code Agent on local Ollama for privacy, Data Analyst on a powerful vLLM-hosted model, or Travel Planner on NVIDIA NIM for GPU-optimized inference. Just change the "model" field in each agent's config.
Any server that implements the OpenAI Chat Completions API format works as a provider. This includes LM Studio, LocalAI, text-generation-inference, and more. Just add the endpoint to config.json.
Agents
An agent is an AI personality with a specific role, model, and tools. All agents are defined in config/agents.json.
General Assistant
All-purpose assistant for Q&A, email, files, API calls, weather, and more.
Research Agent
Finds and summarizes information from the web. Reads URLs and extracts data.
Code Agent
Writes, reviews, and executes code. Manages files and databases.
Data Analyst
Analyzes data with calculations, database queries, and chart generation.
Communication Agent
Drafts and sends professional emails, reports, and newsletters.
DevOps Agent
Scripts, automation, file management, database ops, and API integrations.
Document Agent
Processes, analyzes, and converts documents (PDF, CSV, text, etc.).
Reporting Agent
Generates data reports with charts, tables, and email delivery.
Web Scraper Agent
Extracts data from web pages, processes APIs, and saves structured results.
Security Agent
Generates passwords/tokens, tests APIs, and audits configurations.
Utility Agent
Quick actions: weather, time, calculations, URL shortening, conversions.
ATS Resume Agent
Analyzes resumes against job descriptions for ATS compatibility scoring.
Newsletter Agent
Researches and compiles news briefings with multiple web searches.
Travel Planner Agent
Plans trips with itineraries, flight search, maps, and weather forecasts.
SlideForge
Creates stunning slide deck presentations using Marp. Supports 8 built-in themes and HTML/PDF/PPTX output.
DB Query Agent
Connects to your configured databases (PostgreSQL, SQLite, MS SQL) via SSH tunnels and answers natural-language questions using SELECT queries. Read-only by design.
BrowseForge
Browse websites with a real Chromium browser — navigate, interact with pages, fill forms, extract data, and take screenshots.
Agent Builder
Create, configure, and save new AI agents and workflows through natural conversation. Describe what you need — the builder handles the rest.
Agent Parameter Reference
Each agent has tunable parameters that control its behavior. These can be adjusted per-agent via the Config Editor.
| Parameter | Description | Recommended Range | Notes |
|---|---|---|---|
temperature |
Controls response randomness. Lower = more precise, higher = more creative. | 0.1–0.7 |
Use 0.1–0.3 for code/data/security agents, 0.4–0.6 for creative/communication agents, 0.7 for general chat. |
max_tokens |
Maximum tokens the LLM can generate per response. | 2048–16384 |
Use 2048 for quick tasks (utility), 4096 for emails/scripts, 8192 for reports/code, 16384 for long-form output (itineraries, newsletters). |
max_tool_iterations |
Max LLM→tool round-trips per request. Each iteration can execute multiple tools in parallel. | 2–8 |
Use 2 for single-tool agents (utility), 3–5 for multi-step agents (research, code, data), 8 for complex planners (travel). |
timeout |
Soft timeout in seconds. Checked between LLM iterations — never kills a mid-flight call. When exceeded, returns partial results from tools completed so far. | 60–300 |
Use 60 for quick utility agents, 120 for standard agents, 180 for multi-step research/code agents, 300 for complex planners (travel). The frontend auto-adjusts its timeout to match. |
max_delegation_depth |
Maximum nesting depth for sub-agent delegation chains. | 1–3 |
Default: 3. Use 1 for parent agents that delegate to leaf agents (prevents infinite chains). |
context_chips |
Defines contextual quick-option buttons shown in the chat UI when this agent is selected. Supports static options array or dynamic source from an API endpoint. See the Context Chips section for full config reference. |
Optional JSON object | Example: SlideForge shows theme chips; Newsletter Agent could show tone chips. Users can configure this via the Agent Edit modal. |
use_memory |
Whether to inject long-term memory facts (user preferences, name, past statements) into the system prompt. Disable for task-focused agents so the LLM isn't distracted by user preferences. | true / false |
Default: false. Only the General Assistant has true. Does not affect short-term conversation history — use short_term_memory_window for that. |
short_term_memory_window |
Number of recent conversation messages kept in context for each LLM call (sliding window). Larger values improve follow-up coherence but increase prompt token count — especially significant for agents with large tool payloads (schemas, query results). | 0–20 |
Default: 20. Use 0–6 for data/task-focused agents (DB Query, Scraper) to prevent prompt token bloat from accumulated tool results. Use 10–20 for conversational agents (General Assistant). Has no effect when keep_history: false. |
keep_history |
Whether to write each turn into short-term memory after the response. When false, the agent is fully stateless per-turn — no conversation history is stored or sent on subsequent requests. |
true / false |
Default: true. Set to false for pure task agents like DB Query Agent, where each request is self-contained and history would only inflate prompt tokens. Workflow steps always force keep_history=false regardless of this setting. |
General (0.2, 65500, 3, 120s, 20) • Researcher (0.5, 8192, 5, 180s, 20) • Coder (0.2, 8192, 3, 180s, 20) • Analyst (0.3, 8192, 5, 180s, 20) • Communicator (0.6, 8192, 5, 300s, 20) • DevOps (0.2, 4096, 5, 180s, 20) • Document (0.4, 8192, 3, 120s, 20) • Reporter (0.4, 8192, 5, 180s, 20) • Scraper (0.3, 4096, 5, 180s, 20) • Security (0.2, 4096, 3, 120s, 20) • Utility (0.3, 2048, 2, 60s, 20) • ATS Resume (0.1, 16384, 2, 60s, 20) • Newsletter (0.4, 16384, 3, 180s, 20) • Travel (0.3, 16384, 8, 300s, 20) • DB Query (0.1, 16384, 5, 120s, stm=1) • BrowseForge (0.3, 16384, 15, 180s, 20) • Agent Builder (0.4, 16384, 15, 300s, 20)
Sub-Agent Delegation
delegate_to_agent tool. For example, asking "Search for latest AI news" triggers delegation to the Research Agent. See the Delegation section for full details.
How to Use an Agent
Select an Agent
Click any agent in the sidebar. Make sure you're in "Agents" mode.
Type Your Message
Type in the input box. Press Enter to send (Shift+Enter for new line).
Get a Response
The agent thinks and replies. Tool outputs appear in collapsible blocks.
Sub-Agent Delegation
Agents can intelligently delegate tasks to specialized sub-agents at runtime using LLM function calling. This enables a meta-agent architecture where a general assistant routes complex tasks to domain experts.
How It Works
User Sends Prompt
The user asks the General Assistant a question that requires specialized knowledge or tools.
LLM Decides to Delegate
The LLM sees the delegate_to_agent tool and recognizes a sub-agent has the right tools for the task.
Sub-Agent Executes
The sub-agent runs with its own tools, model, and iteration budget, then returns the result to the parent.
Configuration
Add sub_agents to any agent in config/agents.json or via the Config Editor:
{
"id": "general",
"name": "General Assistant",
"sub_agents": ["researcher", "coder", "analyst"],
"max_delegation_depth": 3,
"delegation_strategy": "supervised"
}
Configuration Fields
| Field | Type | Default | Description |
|---|---|---|---|
sub_agents |
string[] | [] |
List of agent IDs this agent can delegate to |
max_delegation_depth |
number | 3 |
Maximum nesting depth for delegation chains (prevents infinite loops) |
delegation_strategy |
string | "auto" |
How the parent handles delegation results: auto, supervised, or consensus |
Delegation Strategies
Auto
The parent delegates and accepts the result as-is. Simple, fast, token-efficient. Best for trusted sub-agents with well-defined capabilities.
Supervised
After receiving the sub-agent's result, the parent LLM evaluates quality and can retry with refined instructions or redirect to a different sub-agent.
Consensus
The parent dispatches the same task to multiple sub-agents in parallel, then compares their responses and synthesizes the best answer.
Safety Guards
| Guard | What It Prevents | Configurable |
|---|---|---|
| Depth Limit | Infinite recursion (A → B → C → A → ...) | max_delegation_depth |
| Authorized List | Agent calling unauthorized sub-agents | sub_agents array |
| Iteration Budget | Excessive token consumption per sub-agent | max_tool_iterations |
Live Progress
When delegation happens, the chat UI shows real-time status updates via WebSocket:
- "⤵ Delegating to Research Agent..." — toast notification when delegation starts
- Purple delegation card — shows the full delegation chain with nested sub-tool calls
- Sidebar badge — agents with sub-agents show a purple "⤵ N sub-agents" pill
Example: General Assistant with Supervisor
User: "Find the top 5 AI breakthroughs of 2026"
1. General Assistant receives the prompt
2. LLM calls delegate_to_agent(agent_id="researcher", task="Find top 5 AI...")
3. Toast: "⤵ Delegating to Research Agent..."
4. Research Agent runs web_search → read_url → synthesizes results
5. [SUPERVISOR] General Assistant evaluates the response
6. If quality is good → presents to user
7. If incomplete → retries with refined instructions
Connectors
Connect the AI to your databases and external REST APIs — with encrypted credentials, SSH tunnelling, and SSRF-hardened HTTP connectors. Managed at /connectors.
- SSH Connector — A jump-host profile (host, port, user, auth). Reusable across multiple DB connectors.
- Database Connector — Engine, host, port, database name, and credentials. Optionally links to an SSH connector for tunnelling.
- HTTP API Connector — Base URL, authentication (Bearer / API Key / Basic), and optional endpoint hints. Powers the Create API Agent workflow for instant REST API agents.
Supported Database Engines
| Engine | Driver | SSH Tunnel | Notes |
|---|---|---|---|
| PostgreSQL | psycopg2-binary |
Supported | Full SSH tunnel support. Default port 5432. |
| SQLite | Python stdlib | N/A | Local file only. SSH tunnel not applicable. Path relative to user's workspace. |
| MS SQL Server | pymssql |
Supported | Full SSH tunnel support. Default port 1433. |
Setup Workflow
Open Connectors
Go to /connectors or click Connectors in the sidebar.
Add SSH (optional)
If your DB is on a private server, click + Add Connector, choose SSH, and fill in host/user/auth.
Add Database
Add a Database connector. Select your SSH connector (or None for direct). Test the connection.
Use DB Query Agent
Open Chat, select ️ DB Query Agent, and ask your question in plain English.
SSH Authentication
| Method | What to Provide | Notes |
|---|---|---|
| Password | SSH username + password | Standard password-based SSH login. Credentials are encrypted at rest. |
| Private Key (PEM) | SSH username + full PEM key text | Paste the full contents of your .pem key file. The key is encrypted before storage and
written to a temp file only during the connection. |
Security Model
| Layer | Protection |
|---|---|
| Per-User Isolation | Connectors are stored in each user's private workspace directory
(workspace/users/<email>/data/connectors.json). One user can never see another's
connectors. |
| Encryption at Rest | Passwords and private keys are encrypted using Fernet symmetric encryption with a
per-user key derived from SHA-256(JWT_SECRET + user_email). Raw secrets are never stored in
plaintext. |
| API Masking | All REST API list endpoints return *** in place of encrypted credential fields. Decrypted
values are only accessed inside the tool layer — never sent over HTTP. |
| SELECT-Only Enforcement | The query_connector tool unconditionally blocks all non-SELECT SQL (INSERT, UPDATE, DELETE,
DROP, ALTER, CREATE, EXEC, MERGE, etc.) via a keyword blocklist. No agent instruction can
override this. |
| SSH Deletion Guard | Deleting an SSH connector that is still referenced by one or more DB connectors returns a 409 Conflict error, listing the dependent connectors. You must remove those DB connectors first. |
| SSRF Protection (network_guard) | All connector hosts (SSH and DB) are DNS-resolved at save time. Private/internal IPv4 ranges
(127.x.x.x, 10.x.x.x, 172.16-31.x.x, 192.168.x.x,
link-local 169.254.x.x) are blocked for non-admin users. This prevents Server-Side Request
Forgery (SSRF) and DNS rebinding attacks where an attacker tricks the server into connecting to an
internal host. |
| Role-Based Access Control | Only users with admin or superadmin roles may configure connectors targeting
private/internal addresses (e.g. for on-premise databases). The superadmin role is
automatically assigned to the first registered user. Role assignments are managed by the superadmin only
— users cannot self-elevate. |
All three agent tools (list_db_connectors, schema_connector,
query_connector) enforce this. Even if the LLM's instructions say "run DELETE FROM ...", the
tool layer blocks it before execution. This is enforced in Python — not in the prompt.
DB Query Agent
The ️ DB Query Agent is a pre-built agent that uses the three connector tools to answer natural-language questions about your database data.
| Property | Value |
|---|---|
| Agent ID | db_agent |
| Temperature | 0.1 (deterministic SQL generation) |
| Max Tool Iterations | 5 |
| Timeout | 120s |
| Tools | list_db_connectors, schema_connector, query_connector,
generate_chart, transform_json |
| Context Chips | Dynamically loads your configured DB connectors as clickable chip shortcuts |
Agent Workflow (enforced by system prompt)
- [Optional shortcut] If a connector is pre-selected via the ️ Connector chip, skip step 2
and go straight to
schema_connector. - Call
list_db_connectorsto discover available databases. The returnedconnectors[]list defines the only valid connector IDs the agent may use. - Call
schema_connectoron exactly one connector — the one the user wants to query. Never called on all connectors, and never called on an ID not in the list. - Read the returned compact TOML schema to get exact table and column names.
- Explain the planned SQL in plain English before executing.
- Call
query_connectorto run the SELECT statement. - Present results as a markdown table with key insights.
- Optionally call
generate_chartfor numeric data.
The ️ Connector chip in the chat input automatically inserts
[connector: <uuid>] into your message. When the agent detects this, it skips
list_db_connectors entirely and calls schema_connector directly — saving one full
tool round-trip per query.
Example Prompts
| Prompt | What the Agent Does |
|---|---|
| "How many users signed up this month?" | Discovers DB → introspects users table → runs SELECT COUNT(*) WHERE created_at >= ...
|
| "Show me the top 10 orders by total value" | Finds orders table → runs SELECT ... ORDER BY total DESC LIMIT 10 → renders a table |
| "Plot monthly revenue for the last 6 months" | Queries revenue → generates a bar chart using generate_chart |
| "Which products are out of stock?" | Checks inventory table → SELECT name WHERE stock = 0 |
Connector Agent Tools
| Tool | Purpose | Parameters |
|---|---|---|
list_db_connectors |
Returns all database connectors available to the user (id, name, engine, has_ssh). No credentials returned. | None |
schema_connector |
Returns the full table & column schema for a given connector in compact TOML format
(see below). Supports PostgreSQL (information_schema), SQLite
(PRAGMA table_info), and MS SQL (INFORMATION_SCHEMA). The agent uses the
returned schema to write correct SQL without guessing names. |
connector_id (required) |
query_connector |
Executes a SELECT query. Returns columns + rows as a compact CSV
string (header row + data rows) — column names appear once, not repeated per row, saving
60–70% tokens vs JSON. When truncated, numeric summaries (min/max/sum/avg) are also returned. Use
save_as_csv=true to stream the full result to a workspace CSV file — LLM only receives a
small confirmation and the user gets an inline ⬇ Download CSV button. |
connector_id, sql (required); max_rows (int, default 100);
save_as_csv (bool, default false) |
Connector REST API
All endpoints require a valid Bearer token (JWT). All data is scoped to the authenticated user.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/connectors |
List all connectors (secrets masked). Optional ?type=ssh or ?type=database
filter. |
GET |
/api/connectors/ssh-list |
Returns a minimal list of SSH connectors for the DB form SSH tunnel dropdown. |
POST |
/api/connectors |
Create a new connector. Body: full connector object with plain-text secrets (encrypted before saving). |
PUT |
/api/connectors/{id} |
Update a connector. Only re-encrypts credentials if new non-empty values are provided. |
DELETE |
/api/connectors/{id} |
Delete a connector. Returns 409 if an SSH connector is still referenced by DB connectors.
|
POST |
/api/connectors/{id}/test |
Live connection test. SSH: opens and closes an SSH session. DB: runs SELECT 1. |
Connector Data Model
SSH Connector
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Always "ssh" |
|
name |
string | Display name (e.g. "Prod Bastion") | |
ssh_host |
string | SSH server hostname or IP | |
ssh_port |
integer | Default: 22 | |
ssh_user |
string | SSH username | |
ssh_auth |
string | "password" or "key". Default: "password" |
|
ssh_password |
string | Required when ssh_auth="password". Encrypted at rest. |
|
ssh_key |
string | PEM key text when ssh_auth="key". Encrypted at rest. |
Database Connector
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Always "database" |
|
name |
string | Display name (e.g. "Prod Orders DB") | |
db_engine |
string | "postgresql", "sqlite", or "mssql" |
|
db_host |
string | DB server host (omit for SQLite) | |
db_port |
integer | DB port. Default: 5432 (PG) / 1433 (MSSQL) | |
db_name |
string | Database name (or SQLite file path relative to workspace) | |
db_user |
string | Database username | |
db_password |
string | Database password. Encrypted at rest. | |
ssh_connector_id |
string | UUID of an SSH connector to tunnel through. Leave null for direct access. |
Even though the tool layer blocks DML, it is good practice to create a dedicated read-only database user
(e.g. GRANT SELECT ON ALL TABLES TO readonly_user; in PostgreSQL) for the DB Query Agent. This
provides defence-in-depth at the database level.
LLM Token Budget & CSV Export
Without limits, a 50,000-row query result would be ~2.5 MB of JSON — exhausting any LLM context window. Two mechanisms protect against this:
| Mode | How It Works | When to Use |
|---|---|---|
| Inline truncation | Returns up to max_rows rows (default 100, hard ceiling 500). When truncated, the response
includes per-column numeric summaries (min / max / sum / avg) and a note advising the LLM to add
LIMIT or WHERE filters. |
Browsing data, counting, aggregates, ad-hoc queries. |
| CSV Export | Set save_as_csv=true. The full result is streamed to
workspace/query_results/<connector>_<timestamp>.csv. The LLM only receives
{workspace_path, row_count, message} — zero row data goes to the LLM. A green ⬇
Download CSV button appears inline in the chat for immediate download. |
Exporting full tables, reports, 1000+ row data sets. |
Compact TOML Schema Format
Since April 2026, schema_connector returns database schema in a compact TOML-style
string instead of verbose JSON, reducing token usage by ~70–77% for large schemas.
A database with 30 tables × 15 columns:
- Old JSON format: ~13,500 chars ≈ 3,500–4,000 tokens
- New TOML format: ~3,100 chars ≈ 750–900 tokens
- Saved: ~77% fewer tokens just for schema introspection
TOML Schema Output Example
[Alarms] Id:uuid, UserId:uuid, CreatedAt:timestamp without time zone, IsRead:boolean [Orders] Id:uuid, CustomerId:uuid, Total:numeric, Status:character varying, CreatedAt:timestamp without time zone [Users] Id:uuid, Email:character varying, Name:character varying, Role:character varying
The agent reads the schema field (a string) from the tool response. The schema_hint
field in the response reminds the LLM to use exact names when writing SQL.
Clicking ⬇ Download CSV triggers a short-lived (10-minute) signed JWT
download token issued by POST /api/workspace/issue-download-token — the file is served via
GET /api/workspace/download-direct?token=... without requiring an Authorization header,
enabling native browser download dialogs. Tokens are cryptographically tied to the user and file path and
expire automatically.
HTTP API Connectors
HTTP API Connectors let agents call any REST API securely — credentials are Fernet-encrypted and injected server-side; the LLM never sees them. Configure at /connectors → HTTP API tab.
A saved profile that stores a REST API's base URL, authentication method, and optional
endpoint hints. Agents call the API via three tools (list_http_connectors,
describe_http_connector, call_http_connector) — credentials are injected
automatically at execution time and never exposed to the LLM or frontend.
HTTP API Setup Workflow
Open HTTP API Tab
Go to /connectors, click + Add Connector, and choose the HTTP API tab.
Enter Base URL & Auth
Enter the API's base URL (e.g. https://api.example.com/v1), choose auth type, and paste
your token or credentials.
Add Endpoint Hints
Optional but recommended. Add named endpoints (method + path + label) — e.g. GET /objects
→ "Get Products". These become context chip shortcuts in Chat.
Create API Agent
Click Agent on the connector card. AgentForge instantly creates a pre-configured agent with the HTTP tools and context chips — no manual setup required.
Authentication Types
| Type | Header Injected | What to Provide |
|---|---|---|
| Bearer Token | Authorization: Bearer <token> |
OAuth2 / JWT token or API key used as a bearer token |
| API Key | X-Api-Key: <key> |
Static API key (e.g. as used by many SaaS APIs) |
| Basic Auth | Authorization: Basic <base64> |
Username + password, Base64-encoded automatically by the tool layer |
| None | — | No authentication header. Suitable for public APIs. |
Security Model — HTTP Connectors
| Layer | Protection |
|---|---|
| Fernet Encryption | Tokens and passwords are encrypted with SHA-256(JWT_SECRET + user_email)-derived Fernet
keys. Raw secrets are never stored in plaintext. |
| API Masking | All list/get endpoints return *** for credential fields. Decryption only happens inside
the tool layer at execution time. |
| SSRF Protection | All outbound requests are validated before execution. Private IPv4 ranges
(10.x, 172.16-31.x, 192.168.x, 169.254.x) are
blocked. localhost / 127.0.0.1 is permitted only for desktop/Nuitka builds
where local tool providers run on loopback. |
| 64 KB Response Cap | API responses are truncated to 64 KB before being returned to the LLM to prevent context window exhaustion. |
| Encoding Compatibility | All HTTP requests force Accept-Encoding: gzip, deflate — Zstandard (zstd)
is excluded because it is not supported by httpx, preventing CDN-induced
DecodingError crashes. |
Endpoint Hints & Context Chips
Each saved endpoint hint (method + path + name) becomes a clickable
context chip in the Chat UI when the matching API Agent is selected.
When you click a chip (e.g. Get Products), the chat input is prefixed with:
[connector:<id> endpoint:GET /objects] your message here
The API Agent reads the connector:<id> and
endpoint:METHOD /path directly from the prefix and calls
call_http_connector immediately — skipping the
list_http_connectors discovery step and saving one full tool round-trip.
Create API Agent
Clicking Agent on a connector card triggers a one-click agent creation flow:
- The backend generates a fully configured agent JSON — model, system prompt, tools, context chips.
- The frontend fetches the user's existing agent list, merges the new agent (prompts to overwrite if an agent with the same ID already exists).
- The three HTTP tools (
list_http_connectors,describe_http_connector,call_http_connector) are automatically added to the user's tool list if not already present. - The agent list is saved and the orchestrator is reloaded — the agent is live immediately.
- A prompt offers to navigate directly to Chat with the new agent selected.
The generated agent inherits the user's currently configured default model from their settings — it is ready to use without any manual editing.
HTTP Connector Agent Tools
| Tool | Purpose | Parameters |
|---|---|---|
list_http_connectors |
Returns all HTTP connectors for the user (id, name, description, base_url, auth_type, endpoint count). No credentials returned. | None |
describe_http_connector |
Returns full details of a specific connector including endpoint hints (method, path, name). Used by the agent to understand available endpoints before calling them. | connector_id (required) |
call_http_connector |
Executes an HTTP request against the connector's base URL. Credentials are injected server-side. Response is capped at 64 KB. Supports query params, request body, and custom headers. | connector_id, method, path (required);
query_params, body, headers (optional) |
HTTP Connector REST API
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/connectors?type=http |
List all HTTP connectors (secrets masked as ***). |
POST |
/api/connectors |
Create a new HTTP connector. Body: full connector object with plain-text credentials (encrypted before saving). |
PUT |
/api/connectors/{id} |
Update an HTTP connector. Credentials are only re-encrypted if new non-empty values are provided. |
DELETE |
/api/connectors/{id} |
Delete an HTTP connector. |
POST |
/api/connectors/{id}/test |
Live connectivity test — makes a GET request to the base URL with auth headers and
reports status code and latency. |
GET |
/api/connectors/http-chips/{id} |
Returns the endpoint hint chips for a connector as
{"chips": [{name, hint, method, path}]}. Used by the Chat UI context chips
system. |
POST |
/api/connectors/{id}/create-api-agent |
Generates a pre-configured API Agent JSON for this connector. Returns agent config with model, system prompt, tools, and context chips already wired up. |
HTTP Connector Data Model
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Always "http" | |
name | string | Display name (e.g. "My REST API") | |
description | string | Optional description shown in the card and injected into the agent system prompt | |
http_base_url | string | Base URL (e.g.
https://api.example.com/v1). Must be HTTPS for non-localhost URLs. | |
http_auth_type | string | "bearer",
"apikey", "basic", or "none". Default:
"none" | |
http_token | string | Bearer token or API key. Fernet-encrypted at
rest. Returned as *** in API responses. | |
http_basic_user | string | Username for Basic auth. | |
http_basic_password | string | Password for Basic auth. Fernet-encrypted at rest. | |
endpoints | array | List of endpoint hint objects:
[{method, path, name}]. Displayed as context chips in Chat. |
Tools
Tools give agents the ability to perform real actions. Defined in config/tools.json.
Core Tools
| Tool | What It Does | Example Prompt |
|---|---|---|
web_search | Searches the web using DuckDuckGo | "Search for latest AI news" |
calculator | Evaluates math expressions | "What is 2^10 + sqrt(144)?" |
get_current_time | Returns current date/time in any timezone | "What time is it in Tokyo?" |
code_executor | Runs code in a sandboxed environment. Guardrails block 30+ dangerous patterns (shell commands, file deletion, network access, eval/exec) | "Write and run a fibonacci function" |
Communication & Web
| Tool | What It Does | Example Prompt |
|---|---|---|
send_email | Sends emails via SMTP (config/email.json) | "Send an email to john@example.com about the project update" |
read_url | Fetches and extracts readable text from web pages | "Read the content from https://example.com" |
api_request | Makes HTTP requests to REST APIs (GET/POST/PUT/DELETE) | "Call the GitHub API to list my repos" |
shorten_url | Shortens URLs using is.gd | "Shorten this URL: https://example.com/very/long/path" |
get_weather | Current weather for any city (free API, no key needed) | "What's the weather in Hyderabad?" |
search_map | Search for places, landmarks, or find nearby POIs (restaurants, hospitals, ATMs, parks, hotels, etc.) using free OpenStreetMap APIs. Returns names, addresses, distances, and Google Maps links. | "Find restaurants near Banjara Hills" · "Where is the Taj Mahal?" |
Files & Database
| Tool | What It Does | Example Prompt |
|---|---|---|
read_file | Reads files from the workspace directory | "Read the file report.txt" |
write_file | Creates/writes files in workspace. Auto-versions on name conflicts (file_v2.py). Creates .bak backup on overwrite. Blocks writes to protected dirs. | "Save this data to output.csv" |
list_directory | Lists files and subdirectories | "Show me all files in the workspace" |
query_database | Executes queries on databases | "Create a users table and insert some records" |
list_tables | Shows database tables and schemas | "What tables exist in the database?" |
list_db_connectors | Discovers all database connectors available to the current user (name, engine, SSH status). Used by the DB Query Agent. | "Which databases can I query?" |
schema_connector | Introspects table & column schema for a specific connector. Returns a compact TOML-style string (e.g. [Orders]\nId:uuid, Total:numeric) rather than verbose JSON — reducing schema token usage by up to 77%. Supports PostgreSQL, SQLite, and MS SQL. | "Show me the schema of my orders database" |
query_connector | Executes a SELECT-only SQL query against a configured connector. SSH tunnel is opened and closed per query. All DML/DDL is unconditionally blocked. Returns columns + rows as a compact CSV string (header + data rows) — column names appear once, not repeated per row, saving ~60–70% tokens vs JSON. Returns up to max_rows rows (default 100, hard ceiling 500) with numeric summaries (min/max/sum/avg) when results are truncated. Set save_as_csv=true to stream the full result set directly to a workspace CSV file and get a ⬇ Download CSV button in the chat — bypassing LLM token limits entirely. | "How many orders were placed last week?" · "Export all products to CSV" |
Data & Documents
| Tool | What It Does | Example Prompt |
|---|---|---|
extract_text | Extracts text from PDFs, CSVs, and text files | "Extract the text from report.pdf" |
summarize_document | Quick metadata and preview of documents | "Summarize the document data.csv" |
generate_chart | Creates bar, line, pie, scatter, histogram charts | "Create a bar chart of monthly sales data" |
transform_json | Format, minify, validate, flatten, convert JSON/CSV | "Convert this CSV data to JSON" |
regex_match | Pattern matching, extract emails/URLs/numbers | "Extract all email addresses from this text" |
Security
| Tool | What It Does | Example Prompt |
|---|---|---|
generate_password | Generates cryptographically secure passwords | "Generate a 24-character secure password" |
generate_token | Creates random hex tokens for API keys | "Generate a 64-char API token" |
Presentations
| Tool | What It Does | Example Prompt |
|---|---|---|
create_presentation | Converts Marp Markdown into a real slide deck file (HTML/PDF/PPTX). Supports a theme parameter for automatic CSS injection from the theme catalog. | "Create a presentation about AI trends using the corporate-dark theme" |
list_themes | Lists all available presentation themes with descriptions and tags. Used by the agent for theme discovery. | "What presentation themes are available?" |
️ DB Query Agent — Token Budget & CSV Export
Large query results can exhaust the LLM's context window. The system protects against this at two layers:
| Mechanism | Behaviour |
|---|---|
| Row cap (inline mode) | Default 100 rows, hard-ceiling 500 (ABS_MAX_ROWS). When truncated, the tool returns numeric summaries (min / max / sum / avg) per numeric column so the LLM can still answer aggregate questions. A truncation_note tells the LLM to advise the user to add a WHERE or LIMIT clause. |
CSV export (save_as_csv=true) |
Streams the full result set to workspace/query_results/<name>_<timestamp>.csv. The LLM only receives a tiny confirmation message ({"workspace_path": ..., "row_count": 50000}). A green ⬇ Download CSV button appears directly in the chat — no context budget consumed. |
| Parameter | Type | Default | Description |
|---|---|---|---|
connector_id | string | — | ID of the DB connector to query (required) |
sql | string | — | Read-only SQL statement. Use LIMIT whenever possible. |
max_rows | integer | 100 | Max rows to return inline. Clamped to 500 server-side — LLM cannot exceed this. |
save_as_csv | boolean | false | Stream full results to a CSV file in the workspace instead of returning inline data to the LLM. |
Map Search — Details
The search_map tool supports two search modes:
| Mode | How It Works | Example |
|---|---|---|
| Place Search | Finds a specific address, landmark, or location by name. Returns coordinates, full address, and a Google Maps link. | "Eiffel Tower" · "1600 Pennsylvania Ave" · "Charminar" |
| Nearby Search | Finds points of interest near a location within a configurable radius (default 5 km). Returns distance, address, phone, website, and opening hours when available. | "restaurants near Hyderabad" · "hospitals in Banjara Hills" · "ATMs around Jubilee Hills" |
restaurant · cafe · hospital · pharmacy · school · university ·
bank · atm · hotel · park · gym · supermarket · mall ·
gas station · parking · bus stop · train station · airport ·
temple · church · mosque · museum · library · cinema ·
bar · pub · dentist · doctor · clinic · police · fire station · post office
Map Search uses free OpenStreetMap Nominatim and Overpass APIs. No configuration required — it works out of the box.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | ✅ Yes | What to search for (e.g., "restaurants", "Taj Mahal", "hospitals near Banjara Hills") |
location | string | No | Base location for nearby searches. Leave empty if the query already includes a location. |
radius_km | integer | No | Search radius in km for nearby searches (1–50). Default: 5 |
num_results | integer | No | Max results to return (1–25). Default: 10 |
When you ask a question, the agent decides if it needs a tool. It calls the tool, gets the result, and uses it to form its answer. Tool outputs appear in collapsible blocks — click to expand. The argument filter automatically removes any extra parameters the LLM may hallucinate.
BrowseForge — Browser Automation
| Tool | What It Does | Example Prompt |
|---|---|---|
browse_navigate | Navigate to a URL with a real Chromium browser and extract rendered page content with a numbered element map | "Go to amazon.in and find laptops" |
browse_interact | Click, type, select, scroll, check/uncheck elements using numeric IDs from the element map | "Type 'laptop' in the search box and click search" |
browse_extract | Extract structured data from the current page — tables, links, text, or all text content | "Extract all product links from this page" |
browse_screenshot | Capture a PNG screenshot of the current page. Also auto-captured on errors. | "Take a screenshot of the results" |
browse_session | Manage browser sessions — create, list, close. Sessions persist cookies across conversations. | "Close my GitHub session to save the login" |
browse_execute_script | Execute JavaScript in the page sandbox. Useful for dynamic data or triggering page behaviours. | "Run JS to get the page title" |
🏗️ Agent Builder
| Tool | What It Does | Example Prompt |
|---|---|---|
get_agent_schema | Returns the JSON schema for agent configuration | (Called internally by the Agent Builder) |
get_workflow_schema | Returns the JSON schema for workflow configuration | (Called internally by the Agent Builder) |
list_available_tools | Returns all valid tool IDs the builder can assign to agents | (Called internally) |
list_existing_agents | Returns all user agents to avoid ID conflicts | (Called internally) |
validate_agent_json | Validates agent JSON against the schema before saving | (Called internally) |
save_agent_config | Saves the agent, auto-injects the user's active model, and hot-reloads immediately | "Create a LinkedIn job finder agent" |
validate_workflow_json | Validates workflow JSON against the schema before saving | (Called internally) |
save_workflow_config | Saves the workflow and hot-reloads immediately | "Create a research-then-email workflow" |
Select the 🏗️ Agent Builder in the sidebar and describe the agent or workflow you want. The builder autonomously researches the domain, selects tools, writes the system prompt, and saves the config — the new agent is live immediately.
Security & Guardrails
Multi-layered safety system that protects against malicious code execution, accidental file overwrites, and unauthorized access to sensitive resources.
Defense in Depth
Guardrails are enforced at two layers: prompt-level (instructs the LLM) and code-level (blocks even if the LLM ignores instructions).
dangerous request
RULES block
blocks execution
runs
Code Executor Guardrails
The code_executor tool scans all code for 30+ dangerous patterns before execution. If any pattern is detected, execution is blocked entirely.
| Category | Blocked Patterns | Risk |
|---|---|---|
| Shell Execution | os.system(), os.popen(), os.exec*(), os.spawn*(), subprocess | Arbitrary command execution |
| File Deletion | os.remove(), os.unlink(), shutil.rmtree(), Path.unlink() | Data destruction |
| Network Access | socket, requests, urllib, aiohttp, httpx | Data exfiltration |
| Dynamic Execution | eval(), exec(), compile(), __import__() | Code injection |
| Environment | os.environ, os.getenv(), dotenv | Secret leakage |
| Path Traversal | ../, ..\ | Directory escape |
| Introspection | __builtins__, __subclasses__, globals(), ctypes | Sandbox escape |
File Write Protection
The write_file tool implements a smart auto-versioning strategy to prevent accidental data loss:
| Scenario | Behavior | Example |
|---|---|---|
| New file | Writes directly | script.py → saved |
| File exists (default) | Auto-versions to _v2, _v3, etc. | script.py exists → script_v2.py |
File exists + overwrite=true | Backs up existing as .bak, then overwrites | script.py.bak created, then overwrite |
| Sensitive path | Blocked entirely | config/, core/, static/, .env → |
Existing files are never silently overwritten. The auto-versioning system ensures every version is preserved (script.py, script_v2.py, script_v3.py...) and explicit overwrites always create a .bak backup first.
File Deletion
The delete_file function is completely disabled. All delete attempts return an error asking the user to delete files manually. This prevents any agent from accidentally or maliciously removing workspace files.
Protected Directories
Agents can only write files inside the workspace/ directory. Writes to the following paths are blocked:
| Protected Path | Reason |
|---|---|
config/ | Agent and system configuration files |
core/ | Core engine modules |
static/ | Frontend UI files |
tools/ | Tool implementations |
data/ | Persistent storage (chat history, workspace data) |
.env | API keys and secrets |
.git | Version control |
Session Tracking
Every browser tab generates a unique session ID (via sessionStorage) that is sent with each message and stored in the database. This enables:
| Feature | Status | Details |
|---|---|---|
| Unique session per tab | Active | Format: sess-<uuid>, generated on tab open |
| Persisted in DB | Active | Stored in chat_messages.session_id column |
| Query scoping | Future | History and queries remain global for now |
Prompt-level guardrails instruct the LLM to follow safety rules, but determined users may find ways around them. The code-level enforcement in code_executor.py and file_ops.py is the real safety net — it blocks dangerous operations regardless of what the LLM attempts.
Workflows
Workflows let multiple agents collaborate on a task. Defined in config/workflows.json.
Agent = talk to one specialist directly. Workflow = chain multiple agents together for complex tasks, or auto-route to the best one.
Workflow Patterns
1. Sequential — Agent A → Agent B
Multiple agents run in order. Each agent's output is passed to the next as input. Great for tasks that need different skills in sequence.
a REST API"
best practices
on research
2. Router — Auto-pick Best Agent
An LLM reads your message and automatically picks the best agent to handle it. You don't need to choose!
sorting algorithm"
picks best agent
Available Workflows
Research & Summarize
Flow: Researcher → General
Research a topic, then get a structured summary.
Research & Code
Flow: Researcher → Coder
Research best practices, then generate implementation code.
Analyze & Report
Flow: Analyst → Reporter
Analyze data/problem, then produce a professional report with charts.
Smart Router
Automatically picks the best of all 11 agents for your query.
Scrape & Analyze
Flow: Scraper → Analyst
Extract data from a web page, then analyze the content.
Research & Email
Flow: Researcher → Communicator
Research a topic, then draft and send an email summary.
Document to Report
Flow: Document → Reporter
Process a document, then generate a data-driven report.
Security Audit
Flow: Security → Reporter
Audit code/config for vulnerabilities, then generate a report.
Full Stack Pipeline
Flow: Researcher → Coder → Security
Three-step: research, code, and security review.
How to Use a Workflow
Switch Mode
Click the " Workflows" tab in the sidebar.
Select Workflow
Click a workflow (e.g., "Research & Code"). The header updates.
Type Your Task
Enter your task, e.g. "Build a REST API"
Watch Steps
See each agent's output as numbered steps. Final result combines all.
Sequential workflows call multiple agents in sequence, so they take longer than a single agent. The Smart Router is fastest since it picks only one agent.
Workflows can be triggered automatically via webhooks (external HTTP POST) or cron schedules (time-based). See the Triggers & Automation section for setup instructions, cron syntax, and run log monitoring.
Chat Input Features
Power-user shortcuts and smart features built into the message input area.
Keyboard Shortcuts
| Shortcut | Action | Description |
|---|---|---|
# | Tag message | Add hashtags anywhere in your message to categorize and store it with labels (e.g. #followup #backend) |
#Tags — Message Tagging
Add hashtags anywhere in your message to categorize it. Tags are extracted, displayed as purple pills on the message, and stored in the tags column in the database for filtering and analytics.
What are the best practices for REST API design? #followup #backend #learning
The clean message (without tags) is sent to the agent, while the tags are stored separately in the database for later filtering.
Tags are parsed from your message before it is sent. They appear as purple pills beneath your message bubble, and the agent only sees the clean text — tags are invisible to the AI.
Presentations & Themes
SlideForge creates professional slide deck presentations using Marp and a built-in theme catalog.
SlideForge Agent
SlideForge is a specialist agent that converts topics and content into stunning Marp Markdown presentations. It outputs real slide deck files (HTML, PDF, or PPTX) — not just raw Markdown.
npx (included with Node.js). Marp CLI is used automatically via npx @marp-team/marp-cli — no global install needed.
Theme System Overview
Instead of embedding hundreds of lines of CSS in the agent prompt, themes are stored as standalone CSS files and injected automatically at build time by the create_presentation tool.
User selects theme
Click a theme chip in the chat UI, or mention a style preference in your message.
Agent calls tool
SlideForge writes Marp Markdown and calls create_presentation with the theme parameter.
CSS injected & rendered
The tool loads CSS from config/marp_themes/, injects it as a <style> block, then runs Marp CLI.
Built-in Themes
8 professional themes are included out of the box. Each is a complete CSS file (~100 lines) covering headings, backgrounds, tables, code blocks, and per-slide class overrides.
| Theme ID | Name | Description | Best For |
|---|---|---|---|
corporate-dark |
Corporate Dark | Dark navy background with red accents, gradient slides | Boardrooms, executive presentations |
corporate-light |
Corporate Light | Clean white background, navy headers, professional layout | Client meetings, business reports |
modern-gradient |
Modern Gradient | Vibrant purple-to-blue gradients, bold typography | Startup pitches, tech demos |
minimal-clean |
Minimal Clean | White space, teal accents, maximum readability | Internal reports, documentation |
academic |
Academic | Serif fonts (Georgia), warm cream tones, classic feel | Research, universities, education |
creative-neon |
Creative Neon | Dark background with neon cyan and magenta glows | Gaming, creative agencies, tech events |
nature-earth |
Nature Earth | Earthy greens and warm browns, organic textures | Sustainability, health, wellness |
elegant-gold |
Elegant Gold | Deep charcoal with rich gold accents, luxury feel | Awards, VIP events, premium brands |
Presentation Tools
| Tool | What It Does | Key Parameters |
|---|---|---|
create_presentation |
Converts Marp Markdown into a real slide deck file (HTML/PDF/PPTX). Automatically injects theme CSS when a theme parameter is provided. |
markdown_content (required) — Full Marp Markdownfilename — Output filenameformat — html, pdf, or pptxtheme — Theme ID from catalog
|
list_themes |
Returns all available presentation themes with descriptions and tags. Used by the agent to discover themes dynamically. | No parameters |
Adding Custom Themes
Create CSS file
Create config/marp_themes/my-theme.css with Marp-compatible CSS rules targeting section, h1–h6, table, etc.
Register in _index.json
Add an entry to config/marp_themes/_index.json with id, name, description, and tags.
Reload
Restart the server or reload configs. The new theme appears in the chat UI chips and is available via the theme parameter.
Marp renders each slide as a <section> element. Use section { ... } for base styles, section.lead for title slides, and section.invert for dark slides. See any built-in theme file for reference.
Theme Architecture
config/marp_themes/
├── _index.json ← Theme registry (id, name, description, tags)
├── corporate-dark.css ← Full CSS theme (~100 lines each)
├── corporate-light.css
├── modern-gradient.css
├── minimal-clean.css
├── academic.css
├── creative-neon.css
├── nature-earth.css
└── elegant-gold.css
Context Chips System
When you select SlideForge in the chat, a row of theme chips appears above the input box. This is powered by the generic Context Chips system — any agent can have its own contextual quick-option chips.
How It Works
Each agent can define a context_chips field in its configuration. When the agent is selected in the chat, the UI reads this config and renders clickable chips above the input area.
| Config Field | Type | Description |
|---|---|---|
label |
string | Strip label shown in the UI (e.g., " Themes", "️ Tone") |
options |
array | Static chips: Array of {name, value, color} objects. Rendered directly. |
source |
string | Dynamic chips: Format "api:/api/endpoint|key" — fetches options from an API endpoint. The key specifies which field in the response contains the options array. |
display |
string | Which field to show as chip text (default: "name") |
value |
string | Which field to use as the chip value (default: "value" or "id") |
color_map |
object | Map of {"value": "#hexcolor"} for accent dots per chip |
inject_as |
string | Template prepended to the input on click. {value} is replaced with the selected chip's value. Example: "[theme: {value}]" |
Example: Static Options (Tone Selector)
{
"label": "️ Tone",
"options": [
{"name": "Professional", "value": "professional", "color": "#0f3460"},
{"name": "Casual", "value": "casual", "color": "#06b6d4"},
{"name": "Fun & Playful", "value": "fun", "color": "#f59e0b"}
],
"inject_as": "[tone: {value}]"
}
Example: Dynamic API Source (SlideForge Themes)
{
"label": " Themes",
"source": "api:/api/config/marp-themes|themes",
"display": "name",
"value": "id",
"color_map": {
"corporate-dark": "#e94560",
"modern-gradient": "#667eea",
"elegant-gold": "#d4af37"
},
"inject_as": "[theme: {value}]"
}
Built-in Agent Chips
The following 8 agents come pre-configured with context chips out of the box:
| Agent | Chip Label | Options | Inject Template |
|---|---|---|---|
| SlideForge | Themes | 8 themes (Corporate Dark, Corporate Light, Modern Gradient, Minimal Clean, Academic, Creative Neon, Nature Earth, Elegant Gold) — loaded dynamically from API | [theme: {value}] |
| Code Agent | Language | Python, JavaScript, TypeScript, C#, Java, Go, Rust, SQL | [language: {value}] |
| Data Analyst | Analysis Type | Exploratory, Statistical, Trend Analysis, Comparison, Predictive | [analysis: {value}] |
| Communication Agent | ️ Tone | Professional, Casual, Persuasive, Formal, Friendly | [tone: {value}] |
| Document Agent | Action | Summarize, Extract Text, To JSON, To CSV, Analyze | [action: {value}] |
| Reporting Agent | Report Style | Executive Brief, Detailed Analysis, Dashboard View, With Charts | [style: {value}] |
| Newsletter Agent | Topic | Technology, Business, Science, Health, World News, AI & ML | [topic: {value}] |
| ️ Travel Planner | Budget | Backpacker, Budget, Mid-Range, Luxury, Business | [budget: {value}] |
[language: python] is prepended to your message input. The agent sees this tag and adjusts its response accordingly — writing code in Python, using Python conventions, etc.
You can add, edit, or remove context chips for any agent through the Agent Edit Modal → scroll to the “Context Chips” JSON textarea at the bottom. Paste your config and save — no code changes or restart needed!
BrowseForge
AI-powered browser automation — navigate, interact, extract, and screenshot real web pages with a full Chromium browser. Managed at /browser.
BrowseForge is a Playwright-based browser automation tool that gives AI agents a real Chromium browser. Unlike read_url (plain HTTP + regex), BrowseForge can handle JavaScript-rendered SPAs, fill forms, click buttons, maintain authenticated sessions across conversations, and capture screenshots.
How It Works
Navigate
Agent calls browse_navigate with a URL. A real Chromium browser loads the page.
Read Elements
Page content is returned with a numbered element map: [1: button "Submit"]
Interact
Agent clicks, types, selects using numeric IDs: browse_interact(element_id=1)
Extract / Screenshot
Pull tables, links, text, or capture a PNG screenshot of the current page.
Page Representation
When the agent navigates to a page, content is returned in a token-efficient format with numbered interactive elements:
=== PAGE === Title: GitHub Login URL: https://github.com/login === CONTENT === Sign in to GitHub To continue to GitHub === INTERACTIVE ELEMENTS === [1: input "Username or email address" type=text] [2: input "Password" type=password] [3: button "Sign in"] [4: link "Forgot password?"] [5: link "Create an account"]
The agent uses numeric IDs to reference elements — no CSS selectors or XPath needed:
browse_interact(action="type", element_id=1, value="user@example.com") browse_interact(action="type", element_id=2, value="***") ← from credential vault browse_interact(action="click", element_id=3)
BrowseForge Tools
| Tool | What It Does | Key Parameters |
|---|---|---|
browse_navigate |
Navigate to a URL and extract rendered page content with an element map. Auto-creates a session if one doesn't exist. | url (required); session_name, wait_for (optional) |
browse_interact |
Interact with elements on the current page — click, type, select, scroll, check, uncheck. | action, element_id (required); value (optional) |
browse_extract |
Extract structured data from the current page — tables, links, text, or all text content. | extract_type (required); selector (optional) |
browse_screenshot |
Capture a screenshot of the current page. Saved as a PNG in the workspace. Also auto-captured on errors. | session_name, full_page (optional) |
browse_session |
Manage browser sessions — create, list, close, or close all. Sessions persist cookies across conversations when closed explicitly. | action (required); session_name, credential_name (optional) |
browse_execute_script |
Execute JavaScript in the page sandbox. Useful for extracting dynamic data or triggering page behaviours. | script (required); session_name (optional) |
Session Lifecycle
Browser sessions are named (e.g., "default", "github") and scoped per-user.
| Phase | What Happens |
|---|---|
| Create | browse_navigate(url, session_name="github") — auto-creates a Playwright browser context. If a saved state.json exists on disk, cookies are restored automatically. |
| Use | Navigate, interact, extract data. Session state (cookies, localStorage) accumulates in-memory. |
| Close & Persist | browse_session(action="close", session_name="github") — saves cookies/storage to workspace/data/browser_sessions/github/state.json. |
| Resume | In a new conversation, creating a session with the same name loads the saved state. The browser is fresh but the login state persists. |
Use descriptive session names (e.g., "github", "jira") and close them explicitly to save login state. The "default" session is ephemeral and typically not persisted.
Credential Vault
Store website credentials securely — the AI agent references them by name and never sees raw passwords.
| Property | Detail |
|---|---|
| Encryption | Fernet (AES-256) with a per-user key derived from SHA-256(JWT_SECRET + user_email). Same pattern as DB connectors. |
| Storage | Per-user encrypted credential store. Managed via the /browser page. |
| Usage | browse_session(action="create", credential_name="my_github") — credentials are decrypted server-side and auto-filled. |
| LLM Safety | The agent only sees the credential name — raw passwords are never exposed in prompts or responses. |
Domain Rules
Per-user allowlist and blocklist for controlling which websites the agent can visit.
| Rule Type | Behaviour |
|---|---|
| Allowlist | When non-empty, only listed domains are accessible. Everything else is blocked. |
| Blocklist | Listed domains are always blocked. Takes precedence over the allowlist. |
| SSRF Protection | All RFC-1918 private IPs (10.x, 172.16.x, 192.168.x, localhost) are blocked for non-admin users. Uses the same network_guard.py as connectors. |
Security
| Layer | Protection |
|---|---|
| SSRF Blocking | Private IPs, localhost, and link-local addresses are blocked via network_guard.py. |
| Stealth Mode | Uses playwright-stealth to mask automation fingerprints (navigator.webdriver, CDP flags). Enabled by default. |
| User Isolation | Sessions are keyed by email::session_name. One user cannot access another user's sessions. |
| JS Sandbox | browse_execute_script runs JavaScript in the page sandbox — no Node.js access. |
| Error Forensics | Auto-screenshot on any action failure provides forensic evidence of the error state. |
Configuration
BrowseForge settings are in the browseforge section of config/config.json:
| Setting | Default | Description |
|---|---|---|
headless |
true |
Run Chromium without a visible window. Set false for development/debugging. |
max_concurrent_contexts |
3 |
Maximum concurrent browser contexts. New requests queue when the pool is full. |
navigation_timeout_ms |
30000 |
Timeout for page navigation (30 seconds). |
tool_call_timeout_ms |
60000 |
Timeout for individual tool calls (60 seconds). |
max_content_chars |
8000 |
Maximum characters of page content returned to the LLM. Truncated beyond this. |
stealth_mode |
true |
Enable anti-detection fingerprint masking via playwright-stealth. |
Browser Agent
The BrowseForge agent is a pre-built agent optimised for web browsing tasks.
| Property | Value |
|---|---|
| Agent ID | browser_agent |
| Temperature | 0.3 |
| Max Tool Iterations | 15 (many steps needed for multi-page browsing) |
| Timeout | 180s |
| Tools | browse_navigate, browse_interact, browse_extract, browse_screenshot, browse_session, browse_execute_script, web_search, read_url, write_file |
read_url is fast and lightweight — use it for static pages and articles. BrowseForge is powerful but heavier — use it when you need JavaScript rendering, form filling, authentication, or interaction with dynamic pages.
Example Prompts
| Prompt | What the Agent Does |
|---|---|
| "Go to amazon.in and search for laptops under 50000" | Navigates to Amazon → types in search box → clicks search → extracts product listings |
| "Log into GitHub using my saved credentials" | Creates a named session with credential vault → navigates to login → auto-fills username/password → clicks sign in |
| "Take a screenshot of the Google homepage" | Navigates to google.com → captures screenshot → saves PNG to workspace |
| "Extract all links from https://news.ycombinator.com" | Navigates to HN → uses browse_extract(extract_type="links") → returns structured link data |
Triggers & Automation
Run workflows automatically via webhooks or cron schedules — no manual chat interaction needed.
A trigger connects a workflow to an external event (webhook HTTP POST) or a time-based schedule (cron). When fired, the workflow runs automatically with a configurable static input message. Results are logged with full execution trace.
Trigger Types
| Type | How It Works | Use Case |
|---|---|---|
| Webhook | External systems send a POST request to a unique URL. The linked workflow executes immediately. Optional JSON body {"message": "..."} overrides the static input. |
CI/CD pipelines, GitHub Actions, Slack slash commands, Zapier, IFTTT, monitoring alerts |
| ⏰ Cron | Runs on a time schedule using standard 5-field cron expressions. Managed by APScheduler. Uses the trigger's static input as the workflow message. | Daily reports, hourly data checks, weekly newsletters, scheduled database audits |
Setup Workflow
Create a Workflow
You need a workflow first. Go to /workflows or use the Config Editor to define one.
Add a Trigger
Open the workflow card and click Add Trigger. Choose Webhook or Cron.
Configure
Set the static input (the message sent to the workflow). For cron, enter a cron expression. For webhook, copy the generated URL.
Monitor
View run history, execution trace, and status in the trigger's run log.
Webhook Details
| Property | Detail |
|---|---|
| URL Format | POST /api/hook/{secret_token} |
| Authentication | The raw token is shown once at creation time. Only the SHA-256 hash is stored in the database — the raw token cannot be recovered. |
| Rate Limit | 10 calls per hour per token (sliding window). Returns HTTP 429 when exceeded. |
| Body (optional) | {"message": "custom input"} — overrides the trigger's static input for this execution. |
| Response | {"status": "ok", "workflow_id": "...", "run_id": "...", "duration_ms": ...} |
| Test Fire | Click ▶ Test in the UI to fire the webhook without the raw token (uses authenticated endpoint). |
The raw secret token is returned only once when the trigger is created. It is never stored and cannot be recovered. If lost, delete the trigger and create a new one.
Cron Expressions
Standard 5-field cron syntax (validated by APScheduler):
| Expression | Schedule |
|---|---|
0 9 * * * | Every day at 9:00 AM |
*/30 * * * * | Every 30 minutes |
0 0 * * 1 | Every Monday at midnight |
0 8 1 * * | First day of each month at 8:00 AM |
0 */6 * * * | Every 6 hours |
minute hour day-of-month month day-of-week
Use * for "every", */N for "every N units", and specific numbers for exact values. All times are in UTC.
Run Log & Trace
Every trigger execution is logged with:
| Field | Description |
|---|---|
| Status | success or error (includes ghost-success detection for false positives) |
| Duration | Execution time in milliseconds |
| Output Preview | First 300–500 characters of the workflow's final output |
| Error Message | Error details if the run failed |
| Execution Trace | Click Trace to view the full ActivityLogger trace — every tool call, delegation, and LLM interaction. |
Security
| Layer | Protection |
|---|---|
| Token Hashing | Raw webhook tokens are SHA-256 hashed before storage. The raw token is never persisted. |
| Rate Limiting | In-memory sliding window: 10 calls/hour per token. Configurable via WEBHOOK_RATE_LIMIT and WEBHOOK_RATE_WINDOW environment variables. |
| Per-User Scoping | All trigger CRUD endpoints require JWT authentication. Users can only manage their own triggers. |
| Ghost-Success Detection | Even if a workflow returns without error, the output is checked for known failure phrases and marked as error if found. |
Trigger REST API
All endpoints except the webhook receiver require a valid Bearer token (JWT).
| Method | Endpoint | Description |
|---|---|---|
GET | /api/triggers | List all triggers for the current user. Filter: ?workflow_id=... |
POST | /api/triggers | Create a new trigger. Body: {workflow_id, trigger_type, static_input, cron_expr} |
GET | /api/triggers/{id} | Get a single trigger by ID. |
PUT | /api/triggers/{id} | Update a trigger (static_input, enabled, cron_expr). |
DELETE | /api/triggers/{id} | Delete a trigger and its run log. |
GET | /api/triggers/{id}/logs | Trigger run history (last 50 runs, newest first). |
GET | /api/triggers/{id}/runs/{run_id}/trace | Full execution trace for a specific run. |
POST | /api/triggers/{id}/test | Authenticated test fire — executes the workflow without needing the raw token. |
| Public Webhook Receiver (no auth — uses hashed token) | ||
POST | /api/hook/{raw_token} | Webhook receiver. Rate limited: 10/hour. Optional body: {"message": "..."} |
GET | /api/hook/{raw_token} | Returns a helpful 405 error for browser visits explaining that POST is required. |
JSON Configuration
Everything is controlled by 4 JSON files in the config/ folder. Your personal customisations are stored per-user in the database and merged with global defaults at runtime.
When you save via Config Editor, your agents, workflows, and tools are stored per-user in the database (not the global JSON files). Global files serve as shared defaults; your changes always take precedence without affecting other users.
config/config.json — Global Settings
Controls API providers, defaults, global fallback models, and retry settings. API keys use ${ENV_VAR} syntax — they're read from your .env file. Local providers like Ollama and vLLM also accept an optional API key for cloud-hosted or secured deployments.
{
"default_provider": "openrouter",
"providers": {
"openrouter": { // Default — 100+ models, free tier
"api_key": "${OPENROUTER_API_KEY}",
"base_url": "https://openrouter.ai/api/v1"
},
"openai": { // Direct OpenAI (GPT-4o, etc.)
"api_key": "${OPENAI_API_KEY}",
"base_url": "https://api.openai.com/v1"
},
"ollama": { // Local OR cloud (e.g. Anyscale, Together AI)
"api_key": "${OLLAMA_API_KEY}", // "ollama" for local; real key for cloud
"base_url": "http://localhost:11434/v1" // Or your cloud endpoint URL
},
"vllm": { // Self-hosted OR cloud GPU inference
"api_key": "${VLLM_API_KEY}", // "not-needed" for local; real key for cloud
"base_url": "http://localhost:8001/v1" // Or your cloud endpoint URL
}
},
"defaults": {
"model": "meta-llama/llama-3.3-70b-instruct:free",
"temperature": 0.7,
"max_tokens": 2048
},
"fallback_models": [ // Tried in order if primary fails
"openrouter/free",
"meta-llama/llama-3.2-3b-instruct:free",
"qwen/qwen3-14b:free"
],
"retry": {
"max_retries": 3,
"base_delay_seconds": 2
},
"server": {
"host": "0.0.0.0",
"port": 8000
}
}
config.json under the browseforge key:
headless— Run Chromium without a visible window (default:true)max_concurrent_contexts— Max concurrent browser contexts (default:3)navigation_timeout_ms— Page navigation timeout (default:30000)max_content_chars— Content truncation limit for LLM (default:8000)stealth_mode— Anti-detection fingerprint masking (default:true)
See the BrowseForge section for full documentation.
- Local / self-hosted: Set
OLLAMA_API_KEY=ollamaandVLLM_API_KEY=not-neededin your.envfile. No real key is required. - Ollama Cloud: Set
base_urltohttps://api.ollama.com/v1and use a real API key from ollama.com/settings/keys. Cloud models use a:cloudsuffix (e.g.kimi-k2.5:cloud,deepseek-v3.2:cloud). Free tier is available — see pricing. Each user provides their own API key via onboarding — no shared env var needed on the server. - Cloud-hosted Ollama (e.g. Anyscale, Together AI): Set
OLLAMA_API_KEY=<your-real-key>and updatebase_urlto the provider's endpoint. - Secured vLLM endpoint (e.g. behind an API gateway or cloud GPU service): Set
VLLM_API_KEY=<your-real-key>and pointbase_urlat the remote host.
The ${ENV_VAR} syntax keeps secrets out of JSON – they are resolved at runtime from your .env file (or environment variables in production).
config/agents.json — Agent Definitions
Each agent has an id, name, model, system prompt, tools, temperature, max_tokens, max_tool_iterations, timeout, use_memory, and short_term_memory_window. Agents can optionally override global fallback_models and retry settings. Each user's model choices are saved to the database and merged on top of the global file.
{
"id": "coder",
"name": "Code Agent",
"description": "Specializes in writing and reviewing code",
"model": "meta-llama/llama-3.3-70b-instruct:free",
"system_prompt": "You are an expert software engineer...",
"tools": [
{"id": "web_search", "max_calls": 3}, // Max 3 searches per request
{"id": "get_current_time", "max_calls": 1},
"code_executor", // No limit (plain string)
"calculator"
],
"fallback_models": [ // Optional: overrides global
"qwen/qwen3-14b:free",
"meta-llama/llama-3.2-3b-instruct:free"
],
"retry": { // Optional: overrides global
"max_retries": 5,
"base_delay_seconds": 3
},
"temperature": 0.2, // 0.1–0.7 (lower = precise, higher = creative)
"max_tokens": 8192, // Max output tokens (2048–16384)
"max_tool_iterations": 5, // LLM→tool round-trips per request (2–8),
"timeout": 180, // Soft timeout in seconds (30–600). Default: 120
"sub_agents": ["researcher", "analyst"], // Optional: agents this one can delegate to
"max_delegation_depth": 3, // Optional: max nesting depth (default: 3)
"use_memory": false, // Inject long-term facts into prompt (default: false)
"short_term_memory_window": 20, // Recent message history window (default: 20, use 0-6 for data agents)
"keep_history": true, // Store turns in short-term memory (default: true, set false for stateless agents)
"delegation_strategy": "supervised" // Optional: auto | supervised | consensus
}
Per-agent fallback_models and retry settings override the global ones from config.json. If an agent doesn't specify them, the global defaults are used automatically.
max_tool_iterations— Controls how many LLM→tool round-trips are allowed per request. Each iteration = 1 LLM call that may return multiple tool calls executed in parallel. Typical values:2for simple agents,3–5for multi-step agents,8for complex planners. Higher values allow multi-step workflows but consume more tokens.max_tokens— Maximum tokens the LLM can generate per response (output only). Does not limit the input/prompt size. Use2048for quick tasks,4096–8192for reports/code,16384for long-form output (itineraries, newsletters).temperature— Controls response randomness (0.1–0.7). Use low values (0.1–0.3) for code/data/security, medium (0.4–0.6) for communication/writing, higher (0.7) for general conversation.timeout— Soft timeout in seconds. Checked between LLM iterations — never interrupts a running call. When exceeded, the agent breaks out of its tool loop and produces a summary with partial results (“Here's what I found so far…”). Set60for utility agents,120–180for standard agents,300for complex planners. The frontend automatically extends its timer totimeout + 30sbuffer.- Per-tool limits — Tools in the
toolsarray can be a plain string (unlimited) or an object like{"id": "web_search", "max_calls": 3}. When a tool reaches its limit, it's removed from the LLM's available tools so the model naturally moves on. use_memory— Whether to inject long-term memory facts (user name, preferences) into the system prompt. Default:false. Only enable for conversational agents (e.g. General Assistant). Does not control conversation history — useshort_term_memory_windowfor that.keep_history— Whether to write each turn into short-term memory after the response. Default:true. Set tofalsefor pure task agents (e.g. DB Query Agent) where each request is self-contained — this makes every turn fully stateless and eliminates all prompt token overhead from accumulated history. Workflow steps always forcefalseregardless of this setting.
Both settings are configurable per-agent via the Config Editor UI.
config/tools.json — Tool Definitions
Maps tool IDs to their module, function name, and parameter schema. Your personal tool overrides are stored per-user in the database and merged with global tools at runtime.
{
"id": "calculator",
"name": "Calculator",
"description": "Evaluates math expressions",
"module": "tools.calculator", // module path
"function": "calculate", // Function to call
"parameters": {
"expression": {
"type": "string",
"required": true
}
}
}
config/workflows.json — Workflow Definitions
Defines multi-agent workflows with steps and context passing. During onboarding, users choose which workflows to enable — those choices are saved to the database. Editable any time via Config Editor.
{
"id": "research_and_code",
"pattern": "sequential",
"steps": [
{
"agent_id": "researcher",
"instruction": "Research: {user_input}", // {user_input} = your message
"output_key": "research" // saves output as "research"
},
{
"agent_id": "coder",
"instruction": "Code based on: {research}" // uses previous output
}
]
}
After editing any JSON config, click the " Reload Configs" button in the UI sidebar. No server restart needed!
Resilience & Fallback
Built-in retry logic with exponential backoff, automatic model fallback, and per-agent soft timeouts for graceful partial results.
How It Works
When a model returns a 429 rate-limit error, the system automatically:
(exponential)
in order
model succeeds
Configuration Hierarchy
Retry and fallback settings can be configured at two levels. Per-agent settings always take priority over global settings.
| Setting | Global (config.json) | Per-Agent (agents.json) | Behavior |
|---|---|---|---|
fallback_models | Applied to all agents by default | Optional override per agent | Agent-level wins if set, otherwise global is used |
retry.max_retries | Default retry count (e.g. 3) | Optional override per agent | Agent-level wins if set, otherwise global is used |
retry.base_delay_seconds | Base delay for backoff (e.g. 2) | Optional override per agent | Agent-level wins if set, otherwise global is used |
max_tool_iterations | Code default: 1 | Per-agent (set to 2–8) | Max LLM→tool round-trips. All built-in agents set this explicitly: 2 (utility), 3–5 (most agents), 8 (travel planner) |
Per-tool max_calls | Not applicable | Inline in tools array | Tools as {"id": "x", "max_calls": N} — exhausted tools removed from schema |
timeout | Code default: 120 | Per-agent (set to 60–300) | Soft timeout in seconds. Checked between LLM iterations — never kills a running call. When exceeded, agent returns partial results with a forced summary. Built-in values: 60s (utility), 120s (standard), 180s (research/code), 300s (travel planner) |
Example: Per-Agent Override
The Code Agent gets more retries and longer delays, while other agents use the global defaults:
{
"id": "coder",
"model": "meta-llama/llama-3.3-70b-instruct:free",
"fallback_models": ["qwen/qwen3-14b:free", "meta-llama/llama-3.2-3b-instruct:free"],
"retry": { "max_retries": 5, "base_delay_seconds": 3 }
}
Only add fallback_models and retry to agents that need different behavior. Agents without these fields automatically inherit the global settings from config.json.
Free models on OpenRouter typically allow 20 requests/minute and 200 requests/day. The retry + fallback system handles these limits automatically, but if you hit them frequently, consider adding your own API key at openrouter.ai/settings/integrations.
Soft Timeout & Partial Results
Complex agents (e.g. Travel Planner with 8 tool iterations) can take several minutes. Instead of a hard timeout that kills the request mid-call and wastes billed tokens, each agent has a soft timeout that checks elapsed time between LLM iterations.
(no wasted tokens)
Check between iterations
data gathered so far"
for tokens spent
- Between iterations — The check happens before starting the next LLM call, so every call that begins is allowed to finish completely.
- No wasted billing — Unlike hard timeouts (e.g.
asyncio.wait_for), a soft timeout never kills a mid-flight API call. You always get value for the tokens consumed. - Timeout-aware nudge — The forced summary call uses a special prompt: "You ran out of time. Provide the best answer using the data gathered so far. Indicate if information is incomplete."
- Frontend sync — The frontend automatically sets its timer to
(agent.timeout + 30s)to allow the summary call to complete before showing a timeout error. - Configurable per-agent — Set via the Agents page editor or directly in
config/agents.json. Range:30–600seconds.
API Reference
All endpoints are available at http://localhost:8000.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/agents | List all configured agents |
GET | /api/workflows | List all configured workflows |
GET | /api/tools | List all tools (with loaded status) |
POST | /api/chat | Send a message to an agent. Body: {"agent_id": "...", "message": "..."} |
POST | /api/workflow | Run a workflow. Body: {"workflow_id": "...", "message": "..."} |
POST | /api/enhance-prompt | Enhance a prompt via AI. Body: {"prompt": "..."}. Returns {"enhanced": "..."} |
POST | /api/reload | Hot-reload all JSON config files |
GET | /api/history | Chat history. Params: ?limit=50&offset=0 |
GET | /api/stats | Aggregate usage stats (total messages, tokens, avg response time) |
GET | /api/config/agents | View raw agents.json content |
WS | /ws/chat | WebSocket for real-time chat with metadata (model, tokens, timing) |
| DB Connector Endpoints (JWT required, per-user scoped) | ||
GET | /api/connectors | List all connectors (secrets masked). Filter: ?type=ssh or ?type=database |
GET | /api/connectors/ssh-list | Minimal SSH connector list for DB form dropdown |
POST | /api/connectors | Create a connector. Secrets are encrypted before saving. |
PUT | /api/connectors/{id} | Update a connector. Only re-encrypts non-empty credential fields. |
DELETE | /api/connectors/{id} | Delete a connector. Returns 409 if SSH is still referenced by a DB connector. |
POST | /api/connectors/{id}/test | Live connection test (SELECT 1 for DB, session open/close for SSH) |
| BrowseForge Endpoints (JWT required) | ||
GET | /api/browser/sessions | List browser sessions (from DB and disk) |
DELETE | /api/browser/sessions/{name} | Delete a saved browser session |
GET | /api/browser/credentials | List saved website credentials (passwords masked) |
POST | /api/browser/credentials | Save a website credential (Fernet-encrypted) |
DELETE | /api/browser/credentials/{name} | Delete a saved credential |
GET | /api/browser/domain-rules | List domain allowlist/blocklist rules |
POST | /api/browser/domain-rules | Add a domain rule (allow or block) |
| Trigger Endpoints (JWT required) | ||
GET | /api/triggers | List all triggers. Filter: ?workflow_id=... |
POST | /api/triggers | Create a trigger (webhook or cron) |
PUT | /api/triggers/{id} | Update a trigger (static_input, enabled, cron_expr) |
DELETE | /api/triggers/{id} | Delete a trigger and its run log |
GET | /api/triggers/{id}/logs | Trigger run history (last 50) |
POST | /api/triggers/{id}/test | Authenticated test fire for webhook triggers |
POST | /api/hook/{token} | Public webhook receiver (no auth, rate limited: 10/hour) |
| Workspace / Files Endpoints (JWT required) | ||
GET | /api/workspace/files | List files in the user's workspace. Param: ?subdir=... |
POST | /api/workspace/upload | Upload a file to the workspace. Supports target subdirectory. |
GET | /api/workspace/download | Download a workspace file. Param: ?path=... |
DELETE | /api/workspace/delete | Delete a workspace file |
| Auth Endpoints | ||
POST | /api/auth/register | Register a new user account |
POST | /api/auth/login | Login and receive a JWT token |
GET | /api/auth/profile | Get the current user's profile (JWT required) |
PUT | /api/auth/profile | Update profile settings (JWT required) |
| Memory Endpoints (JWT required) | ||
GET | /api/memory | List all long-term memory facts for the current user |
DELETE | /api/memory/{id} | Delete a specific memory fact |
New Features
Security Guardrails
Multi-layered safety: 30+ blocked code patterns, file write protection with auto-versioning, protected directories, and disabled file deletion.
Session Tracking
Unique session_id per browser tab stored with every message for future session-based features.
PDF Export
Every message has a PDF button to download the response as a clean, print-friendly PDF document.
Metadata Footer
Each response shows: agent name, model used, response time, and input/output token counts.
Persistent Storage
All chat interactions are saved to data/ with full metadata, raw response JSON, and message tags.
Smart Input
↑↓ history nav, / agent selector, #tags, enhance, and speech-to-text — all built into the input box.
Prompt Enhance
Click or press Ctrl+E to have AI rewrite your prompt for better, more actionable results.
Voice Input
Click the mic button to dictate your message using built-in browser Speech Recognition. Free, no API key needed.
DB Connectors
Per-user encrypted database connector profiles for PostgreSQL, SQLite, and MS SQL — with optional SSH tunnelling. Powered by the DB Query Agent. See the DB Connectors section.
How to Extend
Add new agents, tools, and workflows without writing core code.
Add a New Agent
Edit agents.json
Add a new entry with unique id, system_prompt, and tools array.
Reload
Click " Reload Configs". Your new agent appears in the sidebar!
Add a New Tool
Create Python File
Create tools/my_tool.py with a function. Can be sync or async.
Register in tools.json
Add entry with module path, function name, and parameter schema.
Assign & Reload
Add tool ID to agent's "tools" array. Click Reload.
Add a New Workflow
Edit workflows.json
Add workflow with "sequential" or "router" pattern.
Template Variables
Use {user_input} and {output_key} in instructions.
Reload
Click Reload. New workflow appears under Workflows tab.
Frequently Asked Questions
Common questions about setup, configuration, and usage.
Go to openrouter.ai, sign up for a free account, and create an API key. OpenRouter provides access to 100+ models with a generous free tier — no credit card required. You'll enter this key during the onboarding setup.
Yes — use Ollama or vLLM as your provider. Both run entirely on your local machine or self-hosted server with no internet required. Install Ollama, pull a model (ollama pull llama3.2), then set your agent's model to ollama/llama3.2.
Click the Reload Configs button in the UI sidebar, or call the API endpoint:
POST /api/reload
Your settings are reloaded instantly — no restart needed.
An Agent is a single AI with a specific role, instructions, and set of tools (e.g., a "Researcher" or "Code Agent"). A Workflow chains multiple agents together in sequence or parallel — the output of one agent becomes the input of the next. Use agents for single-purpose tasks, workflows for multi-step pipelines.
Open the Config Editor from the gear menu → click the Agents tab → click Add New Agent. Fill in the name, model, instructions, and tools. Click Save & Reload. The new agent appears in the chat selector immediately.
Yes — each agent has its own "model" field. Use the provider prefix to route to the right backend:
"meta-llama/llama-3.3-70b-instruct:free" // OpenRouter (default) "ollama/llama3.2" // Local Ollama "vllm/mistral-7b-instruct" // Self-hosted vLLM "openai/gpt-4o-mini" // Direct OpenAI "nvidia/llama-3.1-nemotron-ultra-253b-v1" // NVIDIA NIM
AI AgentForge automatically retries using backup models. It tries each model in order with increasing wait times. The fallback chain works silently — the user just sees a response without any interruption.
Make sure the tools are assigned to the agent in the Config Editor. Also check the agent's instructions — it should explicitly instruct the agent to use tools. Free models sometimes need stronger wording like: "You MUST call the tool. Do NOT display the result inline."
You can add custom tools through the Config Editor → ️ Tools tab. Define the tool's name, description, and parameters. Click Save & Reload to make it available — no server restart needed.
It depends on your provider. With OpenRouter, OpenAI, or NVIDIA NIM, your messages are sent to cloud APIs. With Ollama or vLLM, everything runs locally — no data leaves your server. For sensitive workloads (healthcare, legal, finance), use Ollama or vLLM.
Yes — the code_executor tool has built-in guardrails that block 30+ dangerous patterns including shell commands, file deletion, network access, eval/exec, and environment variable access. Write operations are also protected — files in sensitive directories (config/, core/, tools/) cannot be overwritten.
Add hashtags anywhere in your message to label it — e.g., What is REST API? #learning #backend. Tags are extracted before sending, stored separately, and shown as purple pills on the message. The agent only sees the clean text without the tags.
All conversations are saved securely on the server. Each message stores the user input, agent response, model used, token counts, response time, and tags. You can browse history from the Chat History page and view analytics from the Analytics page (both accessible from the gear menu).