Releases: haih-net/agent
Release list
v1.13.0
v1.13.0 — Custom URL Routing & System Logging
🚀 New Features
SiteRoute — Custom URL Routing
- SiteRoute model — new database entity for SEO-friendly custom paths
path— unique full URL path (e.g./my-article)slug— short segment identifierparentId— hierarchical structure supportkBConceptId— 1:1 link to KBConcept
- Next.js fallback routing — arbitrary paths handled via
/_fallback/[...path].tsx - Virtual
urifield — KBConcept returns custom path or default/concepts/{id} - Link components — ConceptLink, PostLink, TaskLink, WorkLogLink use
urifor SEO-friendly URLs - GraphQL API —
siteRoute,siteRoutes,createSiteRouteresolvers
SystemLog
- SystemLog model — centralized logging for system events and errors
Task Management
- Create and edit tasks — full CRUD support for tasks
- Create task link — quick access to task creation
Chat Enhancements
- User current page data — chat messages now include user's current page context
- Autoclose and autoexpanded handlers — improved chat modal behavior
- useStopPropagationScroll hook — prevent scroll event bubbling
Image Generation
- More models — added additional image generation models
- ImageGenerator component update — improved UI and functionality
Markdown
- FilesUploader — markdown editor now supports file uploads
🔧 Technical Changes
Infrastructure
- Self-signed HTTPS for localhost — Traefik websecure entrypoint with TLS support
- Mailhog dev port — exposed port 1025 for local email testing
GraphQL Codegen
- TypedDocumentNode — automatic type inference in Apollo hooks without explicit generics
- Simplified syntax — components no longer need explicit type parameters
SEO
- LocalBusiness JsonLd — added structured data schema
- JsonLd breadcrumbs fix — corrected breadcrumb generation
UI/UX
- dvh units — replaced
vhwithdvhfor better mobile viewport handling - Auth form fix — resolved authentication form issues
- Authed redirect fix — corrected redirect behavior for authenticated users
Code Quality
- findUnique over findFirst — improved query precision
- PrismaContext req types — fixed request type definitions
- Console.log cleanup — removed debug statements
🐛 Bug Fixes
- Fix 404 errors handling
- Fix skills loading
- Fix markdown links
- Fix worklogs link
- Fix tasks searchable
- Fix edit task status
- Fix site origin detection
- Fix AppInitialProps types
- Update tasks page fetch policy
📦 Dependencies
- Upgraded project dependencies
Full Changelog: v1.12.0...v1.13.0
v1.12.0 — Infrastructure & Image Support
🚀 New Features
Post & KBConcept Images
- Post::image — posts now support an optional image field for visual content.
- KBConcept::image — knowledge base concepts can have associated images.
- KBConceptFiles relations — fixed relationships between concepts and files.
Image Generator
- ImageGenerator — new utility for AI-powered image generation.
- LLM client refactoring — improved architecture for LLM integrations with image generation support.
Mermaid Diagrams
- Mermaid support — added Mermaid diagram rendering capability for documentation and content.
Email System
- sendMail resolver — new GraphQL mutation for sending emails via the mail server.
- Mailserver deployment fix — resolved deployment issues with the mail server configuration.
Agent Enhancements
- Skills info in Agent Data — agent data now includes skills information for better context.
- readWebPage utility — new
Utils/readWebPagehelper for fetching and parsing web content.
🔧 Technical Changes
Infrastructure
- Node 22 migration — migrated base image to
node:22-bookwormfor improved performance and security. - Varnish cache — added Varnish cache layer for static assets to improve load times.
- Traefik logs fix — resolved logging issues in Traefik configuration.
- Crypto config — moved cryptographic configuration to environment variables for better security.
Database
- File::CreatedBy rename — renamed the
CreatedByfield in the File model for consistency.
UI Fixes
- Chat width — fixed chat widget width issues.
- ChatWidget scroll — resolved scrolling behavior in the chat widget.
- :disabled styles — fixed styling for disabled form elements.
Code Quality
- hasFieldInSelection helper — added utility for checking field presence in GraphQL selections.
- Translation to English — translated various components to English.
📦 Dependencies
No major dependency changes in this release.
Full Changelog: v1.11.0...v1.12.0
v1.11.0 — Skills Resolver & Browser Compatibility
🚀 New Features
File-Based Skills Resolver
A new GraphQL module that exposes a catalog of agent skills backed by files
on disk. Skills are designed to be stored next to the GraphQL types they
operate on and to ship with optional auxiliary files (markdown templates,
shell scripts, etc.).
- Discovery — the registry recursively scans
server/schema/types/for
files literally namedskillManifest.ts. Skills can therefore live under
any graph-type folder, not only underSkills/skills/. - Identifier — the skill
idis derived from the manifest folder path
relative toserver/schema/types/(POSIX form). Authors never assign ids
manually. - Manifest contract — each
skillManifest.tsmust export a named const
skillManifest: SkillManifest. Invalid or missing manifests are skipped
(with aconsole.errorin development) so a half-written file cannot
break the registry. - Manifest fields —
name, flatdescription, optional
buildContent(ctx)for lazy markdown content (with fullPrismaContext
access), an optional auxiliary file list, and an optionalexecutable
(shellornode) with a typedargsSchema. - Lazy content —
Skill.contentis resolved only if the client selects
it, so listing skills stays cheap. - Executor —
child_process.spawnwith a 60s timeout; declared args are
forwarded as--key valuepairs. Host-side execution is intentional for
now; an isolated Docker runner is planned (task001--docker-service). - Helpers —
renderTemplate({{path.to.value}})for simple runtime
substitution. A full MDX runtime is intentionally not wired up yet. - Example — ships a
hello-worldskill demonstrating manifest, markdown
template using DB user count, and arun.sh.
GraphQL surface:
type Skill {
id: ID!
name: String!
description: String!
content: String # lazy — calls buildContent only if requested
files: [String!]!
hasExecutable: Boolean!
}
type Query {
skills: [Skill!]!
skill(id: ID!): Skill
}
type Mutation {
executeSkill(id: ID!, args: Json): SkillExecutionResult!
}See wiki/skills for the full guide.
Browser Compatibility & E2E Testing
End-to-end coverage for older browsers and a stricter bundle baseline.
- Browserslist — production target now covers Safari/iOS 13+ and modern
Chrome/Firefox/Edge, so Next.js/SWC transpiles the client bundle for
older runtimes. check:bundle— new npm script usinges-checkto verify the
production bundle syntax against the supported baseline (ES2019).- Playwright + WebKit — desktop Safari and mobile iPhone 13 projects
catch runtime errors thates-checkcannot detect (missing APIs,
hydration failures, broken deps).baseURLis read from
PLAYWRIGHT_BASE_URL(defaults tohttp://localhost:3000); the server
is not auto-started. tests/e2e/console-errors.spec.ts— opens pages from aPAGESlist,
listens topageerror/console.errorand fails the test on any
reported error.- Wiki —
wiki/testing/README.mdupdated with usage instructions and
caveats.
🔧 Technical Changes
Build & Bundling
- Webpack instead of Turbopack — Turbopack produced invalid client
chunks (ReferenceError: boolean is not defined) for the
react-markdown/rehypeecosystem.build:frontnow runs
next build --webpack; the Turbopack toggle is gated behind
NEXT_USE_TURBOPACK=true. build:analyze— bundle analyzer script restored on top of the
Webpack build (@next/bundle-analyzer).
Tool: Shell Execute
- The Build Command node now prepends
cd <cwd> &&instead of relying on
child_processcwdoption, fixing edge cases where the target shell
ignored or mis-quoted the working directory.
Docker / Sharp
- Updated the Dockerfile so
sharpresolves correctly in production
images.
📦 Dependencies
@next/bundle-analyzer^16.2.6@playwright/test^1.59.1es-check(dev)
📚 Documentation
- New
wiki/skills/README.mdcovering layout, naming convention, manifest,
GraphQL API, executor, and build notes; linked fromwiki/README.md.
Full Changelog: v1.10.0...v1.11.0
v1.10.0
v1.10.0 — Markdown Editor & Analytics
🚀 New Features
Betterlytics Analytics
Privacy-focused analytics integration using Betterlytics.
- Web Vitals tracking — Core Web Vitals metrics (LCP, FID, CLS)
- Outbound links tracking — Full URL tracking for external links
- Error tracking — JavaScript errors and console errors
Configuration:
NEXT_PUBLIC_BETTERLYTICS_SITE_ID=your-site-id
NEXT_PUBLIC_BETTERLYTICS_SCRIPT_URL=https://your-betterlytics-instance/script.js
NEXT_PUBLIC_BETTERLYTICS_SERVER_URL=https://your-betterlytics-instanceMarkdown Editor Improvements
Extended toolbar and editing capabilities:
- Table editing — Insert and edit tables
- Strikethrough, subscript, superscript — Additional text formatting
- Code blocks — Insert code blocks with syntax highlighting
- Source mode — Toggle between rich-text and source view
- Markdown shortcuts — Standard markdown shortcuts support
Markdown Styles
New styles for markdown content:
- Horizontal rules (
hr) - Task lists with checkboxes
- Subscript and superscript
- Footnotes
🔧 Technical Changes
Fetch Request Tool
- Allow internal hosts and IPs (previously blocked)
- Accept headers and body as objects (not just JSON strings)
- Added input parsing node for flexible parameter handling
Agent Improvements
- Pass request params to agent context
- Change default model to
google/gemini-3.1-flash-lite-preview
🐛 Bug Fixes
- Fix links color in chat widget (white links on user messages)
📦 Dependencies
@betterlytics/tracker^0.2.2
Full Changelog: v1.9.0...v1.10.0
v1.9.0 — LLM Client & Knowledge Base
🚀 New Features
LLM Client & GraphQL API
Direct access to LLM capabilities via GraphQL — no n8n workflows required.
Why this matters:
- Experimentation playground — test message chains, tool calling patterns, and multi-turn conversations directly through GraphQL Playground
- Server-side integration — use
llmClientin resolvers, middleware, and background jobs without workflow overhead - Full OpenAI-compatible API — supports vision, tool calls, and conversation history
Mutations:
llmCompletion— raw text completionllmChatCompletion— multi-turn conversations with support for:- System/user/assistant roles
- Vision (image_url content parts)
- Tool calling history (tool_calls, tool_call_id)
Example 1: Tool Calling History
Simulate assistant tool calls and tool responses in conversation:
mutation llmChatCompletionWithToolHistory {
llmChatCompletion(
input: {
messages: [
{ role: system, content: "You are a calculator. Use the calculate function." }
{ role: user, content: "What is 25 * 4?" }
{
role: assistant
content: null
toolCalls: [
{
id: "call_123"
type: "function"
function: {
name: "calculate"
arguments: "{\"expression\": \"25 * 4\"}"
}
}
]
}
{
role: tool
toolCallId: "call_123"
content: "100"
}
]
}
) {
text
finishReason
usage { promptTokens completionTokens totalTokens }
}
}Example 2: Multi-User Chat Context
Test how the model tracks multiple participants:
mutation llmChatCompletionMultiUserContext {
llmChatCompletion(
input: {
messages: [
{ role: system, content: "You observe a group chat. Track the conversation." }
{ role: user, content: "[Alex]: I finished the ML project today." }
{ role: assistant, content: "Noted: Alex finished ML project." }
{ role: user, content: "[Maria]: Nice! I'm still debugging the database issue." }
{ role: assistant, content: "Noted: Maria has a DB bug." }
{ role: user, content: "[Alex]: Maria, what's the error?" }
{ role: user, content: "[Maria]: Index corruption after migration." }
{ role: user, content: "Questions:\n1. Who finished a project?\n2. What is Maria's problem?\n3. How many people are in the chat?" }
]
}
) {
text
finishReason
}
}Example 3: Chain-of-Thought Reasoning
Guide the model through step-by-step analysis:
mutation llmChainOfThought {
llmChatCompletion(
input: {
messages: [
{
role: system
content: "You are a code reviewer. Analyze code step by step: 1) Identify the purpose, 2) Find potential bugs, 3) Suggest improvements."
}
{
role: user
content: "Review this function:\n\nfunction divide(a, b) {\n return a / b;\n}"
}
]
temperature: 0.3
}
) {
text
finishReason
}
}Example 4: Summarization Pipeline
Build document processing chains:
mutation llmSummarize {
llmChatCompletion(
input: {
messages: [
{ role: system, content: "Summarize text in 2-3 sentences. Be concise." }
{ role: user, content: "The quick brown fox jumps over the lazy dog. This sentence contains every letter of the English alphabet and is commonly used for font testing and typing practice. It was first used by Western Union in the late 1800s to test telegraph equipment." }
{ role: assistant, content: "A pangram sentence containing all alphabet letters, used since the 1800s for testing telegraph equipment and later for font/typing tests." }
{ role: user, content: "Now summarize: GraphQL is a query language for APIs that gives clients the power to ask for exactly what they need. It was developed by Facebook in 2012 and open-sourced in 2015. Unlike REST, GraphQL uses a single endpoint and allows clients to specify the structure of the response." }
]
temperature: 0.2
}
) {
text
finishReason
}
}Server-Side Usage
Use llmClient directly in resolvers for automated processing:
// Auto-generate file metadata from images
async function processFile({ file, ctx }: ProcessFileProps) {
const { prisma, llmClient } = ctx
const imageBuffer = await readFile(join('uploads', file.path))
const base64 = imageBuffer.toString('base64')
const dataUrl = `data:${file.mimetype};base64,${base64}`
const response = await llmClient.chatCompletion({
messages: [
{
role: 'user',
content: [
{ type: 'image_url', image_url: { url: dataUrl } },
{ type: 'text', text: 'Return JSON: { "name": "...", "description": "..." }' },
],
},
],
max_tokens: 500,
temperature: 0.3,
})
const result = JSON.parse(response.choices[0].message.content)
await prisma.file.update({
where: { id: file.id },
data: { name: result.name, description: result.description },
})
}// Auto-tag content based on text analysis
async function autoTagConcept({ concept, ctx }: AutoTagProps) {
const { prisma, llmClient } = ctx
const response = await llmClient.chatCompletion({
messages: [
{ role: 'system', content: 'Extract 3-5 tags from the text. Return JSON array: ["tag1", "tag2"]' },
{ role: 'user', content: concept.content },
],
temperature: 0.2,
})
const tags = JSON.parse(response.choices[0].message.content)
await prisma.kBConcept.update({
where: { id: concept.id },
data: { data: { tags } },
})
}Configuration:
# Add to docker/.env
LLM_API_URL=http://llama:8080/v1Permissions: Both mutations require isSudo.
File Management Module
Full CRUD operations for files with new frontend pages:
- Files list page with pagination and filtering
- File detail page with view and edit modes
- FileItem component for list and full view variants
New File model fields:
description— file descriptioncontent— file content- Unique constraint on
path
GraphQL additions:
FileWhereInput— flexible filtering with where/orderBy paramsupdateFilemutation with permissions
Concepts Management
Complete concepts management system:
- Concepts list page with pagination
- Concept detail page with view and edit form
- ConceptItem component for list and full view variants
GraphQL additions:
conceptquery for fetching single conceptconceptsCountandconceptsConnectionqueriesKBConceptWhereUniqueInputfor single concept queries- Updated
updateConceptmutation with where input and sudo check
KBConceptFile Relation
New many-to-many relation between concepts and files:
- Link files to knowledge base concepts
- Prisma migration for
KBConceptFilejoin table
Concept Hierarchy
Hierarchical structure for knowledge base concepts:
New KBConcept fields:
parentId— parent concept referencerootId— root concept referencecode— unique concept codedata— JSON data field
Relations:
ConceptTree— self-referential parent-childConceptRoot— self-referential root reference
🔧 Technical Changes
GraphQL Filters Refactoring
- Add
StringNullableFilterandQueryModeEnumfor flexible filtering - Add
buildStringNullableFilterWherehelper for reusable filter logic - Consolidate enums from separate files into shared
types/enums.ts - Remove redundant
enums.tsfiles from KB entities
Image Resizer Refactoring
Extract helpers into separate files for better maintainability:
server/middleware/imageResizer/
├── helpers/
│ ├── flattenAlphaToBackground.ts
│ ├── parseBackgroundColor.ts
│ └── resizeImg.ts
├── index.ts
└── interfaces.ts
n8n Workflow Improvements
- Add
hasKBTools,hasUpdateOwnProfileToolconfig options - Inject user profile info into agent context
- Always create graphql request tool workflow
Task Improvements
- Add
assigneeIdfield to Task inputs - Fix create/update task resolvers for assignee handling
🐛 Bug Fixes
- Fix KB queries with improved buildWhere helper
- Fix
getConceptsConnectionQueryVariablesin concepts page - Fix
conceptsResolverwith proper filtering - Fix
imageResizerMiddlewarehandling - Fix
prism-jsin Markdown editor
📁 New Files
server/
├── llm/
│ └── client/
│ ├── index.ts # LLM client implementation
│ └── interfaces.ts # LLM types
├── schema/types/
│ ├── LLM/
│ │ ├── index.ts # LLM GraphQL type
│ │ ├── interfaces.ts # LLM interfaces
│ │ ├── types.ts # LlamaUsage type
│ │ └── resolvers/
│ │ ├── chatCompletion.ts # Chat completion mutation
│ │ └── completion.ts # Text completion mutation
│ └── KBConceptFile/
│ └── index.ts # Concept-File relation
└── middleware/imageResizer/helpers/
├── flattenAlphaToBackground.ts
├── parseBackgroundColor.ts
└── resizeImg.ts
src/components/pages/
├── Files/
│ ├── index.tsx # Files list page
│ ├── interfaces.ts
│ ├── helpers/index.ts
│ ├── View/
│ │ ├── index.tsx
│ │ ├── styles.ts
│ │ └── FileItem/
│ │ ├── index.tsx
│ │ ├── interfaces.ts
│ │ ├── st...
v1.8.0 — Computer Vision
🚀 New Features
Local Image Recognition
The agent can now analyze images locally using Qwen3.5 vision model via llama.cpp. No cloud APIs required — all processing happens on your GPU.
Capabilities:
- Describe images, charts, diagrams
- Analyze mathematical graphs and functions
- Read text from images (OCR)
- Answer questions about visual content
Configuration:
# Main model (4B recommended for vision tasks)
LLAMA_MODEL=unsloth/Qwen3.5-4B-GGUF/Qwen3.5-4B-Q8_0.gguf
# Vision encoder (required for image input)
LLAMA_MMPROJ=unsloth/Qwen3.5-4B-GGUF/mmproj-F16.ggufBoth files are auto-downloaded from HuggingFace on first run (~5 GB total).
OpenAI-Compatible Vision API
Send images via the standard /v1/chat/completions endpoint:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama",
"messages": [{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": "data:image/png;base64,YOUR_BASE64"}},
{"type": "text", "text": "What is in this image?"}
]
}],
"max_tokens": 1000
}'Note: Images must be sent as base64 — llama.cpp doesn't fetch URLs directly.
📚 Documentation
Computer Vision Guide
New documentation for vision capabilities:
- Configuration and setup
- API usage examples
- Troubleshooting common issues
- Performance benchmarks
→ See wiki/computer-vision/README.md
Updated llama-server Documentation
- Added
LLAMA_MMPROJenvironment variable - Added
LLAMA_CTX_SIZEandLLAMA_VERBOSEoptions - Updated model recommendations for vision tasks
🔧 Technical Changes
entrypoint.sh Enhancements
The llama.cpp entrypoint script now handles multimodal projection files:
- Parses
LLAMA_MMPROJenvironment variable (format:owner/repo/filename) - Auto-downloads mmproj from HuggingFace if not present
- Passes
--mmprojflag to llama-server when configured
docker-compose.yml Updates
- Added
LLAMA_MMPROJenvironment variable to llama service - Added
LLAMA_CTX_SIZEfor context window configuration - Added
LLAMA_VERBOSEfor debug logging
💡 Tips
Transparent PNG Handling
Vision models expect RGB images. PNG files with transparency may render incorrectly (transparent areas become black).
Solution: Add a white background before sending:
# Using ImageMagick
convert input.png -background white -flatten output.pngRecommended Settings
| Use Case | Model | VRAM |
|---|---|---|
| Testing | Qwen3.5-0.8B | ~2 GB |
| Production | Qwen3.5-4B + mmproj | ~6 GB |
| High quality | Qwen3.5-4B-BF16 + mmproj | ~10 GB |
Performance
On NVIDIA RTX 3060/4060:
- Image encoding: ~100-300ms
- Text generation: ~40 tokens/sec
📁 New Files
wiki/
└── computer-vision/
└── README.md # Vision setup and usage guide
docker/
└── llama/
└── entrypoint.sh # Updated with mmproj support
⚙️ Configuration
Add to docker/.env:
# Vision model (recommended)
LLAMA_MODEL=unsloth/Qwen3.5-4B-GGUF/Qwen3.5-4B-Q8_0.gguf
LLAMA_MMPROJ=unsloth/Qwen3.5-4B-GGUF/mmproj-F16.gguf
# Optional: increase context for large images
LLAMA_CTX_SIZE=8192
# Optional: enable verbose logging
LLAMA_VERBOSE=1Restart llama service after configuration:
cd docker
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d llamaFull Changelog: v1.7.0...v1.8.0
v1.7.0 — Agent Identity & Security
🚀 New Features
Agent Self-Profile Management
The agent now has full awareness of its own identity and can update its profile autonomously.
What's new:
- Agent receives its profile data (fullname, intro, content) in context
- New
update_profiletool allows the agent to modify its own profile - Built-in safety instructions protect against identity manipulation (prompt injection)
Tool capabilities:
- Update
fullname,intro,contentfields - Reasoning required before any profile change
- Agent maintains identity integrity across sessions
Custom System Message via Credentials
System message can now be configured per agent instance through credentials file (gitignored):
{
"agentName": "Chat Agent",
"systemMessage": "Custom system message for this agent instance"
}Benefits:
- Individual agent tuning without repository changes
- Credentials are gitignored — safe for sensitive instructions
- Override default system message from code
Password Management UI
Administrators can now change user passwords directly from the admin interface.
- New
PasswordFieldcomponent with visibility toggle updateUsermutation accepts password field- Password properly hashed before storage
🔐 Security — Breaking Change
Unified JWT Token System
Complete overhaul of the authentication system:
| Before | After |
|---|---|
| JWT-only verification | Database-backed verification |
| No token revocation | Revocation support via DB |
| Implicit token types | Explicit TokenType enum (Auth, Referrer) |
| Sync verification | Async with Prisma dependency |
What changed:
TokenTypeenum for explicit token classification- Tokens stored in
Tokentable withexpiredAtfield verifyTokenis now async with database lookup- All auth resolvers updated (signin, signup, authEthAccount, authViaTelegram)
Benefits:
- Token revocation (logout from all devices)
- Audit trail of all issued tokens
- Type-safe token handling
- Foundation for multi-device session management
📚 Documentation
Agent Philosophy
New documentation explaining the core ideology:
- What You Get — autonomous entity, not a chatbot
- Agent as First-Class Participant — comparison with traditional assistants
- Core Principles — Transparency, Knowledge, Identity, Autonomy, Local-first
- Experience System — reflexes and behavioral learning
- Agent World — knowledge graph with attention mechanics
→ See wiki/agent-philosophy.md
Updated README
Rewritten introduction emphasizing the unique value proposition:
- Autonomous AI entity with own identity and credentials
- Epistemic knowledge with confidence tracking
- Mandatory reasoning for all actions
🔧 Technical Changes
System Message Refactoring
systemMessagePathreplaced withsystemMessagedirectly- System message reading logic moved to individual workflows
- Removed
base-system-message.mdfrom agent-factory - More flexible — system message can be built programmatically
📁 New Files
wiki/
└── agent-philosophy.md # Core ideology documentation
server/n8n/workflows/
├── agent-chat/nodes/
│ ├── KB/updateProfile/ # Profile update workflow
│ └── execTool/tools/
│ └── updateProfile.ts # Profile update tool
└── helpers/
└── objectToMarkdown.ts # Helper for formatting
src/ui-kit/controls/
└── PasswordField/ # Password input component
⚙️ Migration
- All users must re-authenticate — existing tokens are invalid
- No database migration required — Token table already exists
- Update agent credentials if you want custom system messages
Full Changelog: v1.6.0...v1.7.0
v1.6.0 — Shell Execute Tool
🚀 New Features
Shell Command Execution
Agent can now execute shell commands directly on the host system. This enables autonomous system administration, file operations, and integration with external CLI tools.
Tool capabilities:
- Execute any shell command with arguments
- Specify working directory (
cwd) - Returns stdout, stderr, and exit code
- Full reasoning logging before execution
Usage example (agent perspective):
Tool: shell_execute
Command: git status
Cwd: /app
Security
Shell execution is controlled by the canExecuteShell flag in AgentFactoryConfig. Disabled by default — must be explicitly enabled per agent.
const config: AgentFactoryConfig = {
// ...
canExecuteShell: true,
}🐳 Docker Improvements
Additional Utilities
The app container now includes essential CLI tools for agent operations:
git— version controljq— JSON processingmc— Midnight Commander file managernmap— network explorationsudo— privileged operations
Traefik Routing
Added dedicated route for n8n UI at n8n.localhost for easier workflow debugging during development.
🔧 Build Configuration
Storage Directory Exclusion
The storage/ directory is now properly excluded from:
- TypeScript compilation (
tsconfig.json) - ESLint checking (
eslint.config.cjs) - Prettier formatting (
.prettierignore)
This prevents build errors when storage contains non-TypeScript files or generated content.
📁 New Files
server/n8n/workflows/
├── tool-shell-execute/
│ └── index.ts # Shell Execute workflow
└── agent-chat/nodes/execTool/tools/
└── shellExecute.ts # Tool node definition
⚙️ Configuration
To enable shell execution for an agent, add to agent config:
canExecuteShell: trueThe tool will appear in the agent's available tools and can be called with:
command— shell command to execute (required)cwd— working directory (optional, defaults to/)reasoning— explanation of why this command is needed (required by ExecTool pattern)
Full Changelog: v1.5.0...v1.6.0
Added local llama.cpp
v1.5.0 — Local LLM Server with CUDA Support
🚀 New Features
Local llama.cpp Server
Run AI models locally without external API dependencies. The new llama service is included in docker-compose with full NVIDIA CUDA support.
Key capabilities:
- Auto-download models from HuggingFace on first run
- OpenAI-compatible API (
/v1/chat/completions,/v1/completions) - Configurable via environment variables
- Support for HuggingFace token for gated models
Default model: unsloth/Qwen3.5-0.8B-GGUF/Qwen3.5-0.8B-Q8_0.gguf
⚙️ Configuration
Add to docker/.env:
LLAMA_MODEL=unsloth/Qwen3.5-0.8B-GGUF/Qwen3.5-0.8B-Q8_0.gguf
LLAMA_GPU_LAYERS=99
LLAMA_CTX_SIZE=4096
HUGGINGFACE_TOKEN=hf_xxx... # optional, for gated modelsConfigure credentials/system/openrouter.json:
[
{
"id": "openrouter-cred",
"name": "OpenRouter",
"type": "openRouterApi",
"data": { "apiKey": "llama", "url": "http://llama:8080/v1" }
}
]⚠️ Requirements
- NVIDIA GPU with CUDA support
- CUDA drivers installed on host (
nvidia-smishould work) - Docker with NVIDIA Container Toolkit
📚 Documentation
🏃 Quick Start
cd docker
docker compose -f docker-compose.yml -f docker-compose.dev.yml up llamaFull Changelog: v1.4.0...v1.5.0
1.3.0: feat: Posts module, referral registration, sitemap
🗒️ Posts Module
Full CRUD for posts with revision history. Every update to a post creates a PostRevision snapshot preserving previous content, title, description, intro, status and signature.
Status lifecycle: draft → published → unpublished
Comments are implemented as child posts (parentId / rootId).
Validation: a validatePost query provides pre-flight checks with hard limits (title ≤ 512 chars, description ≤ 3072 chars) and SEO warnings.
AI guideline: a postGuidelines query returns a Markdown guide describing post structure and signing flow — useful for AI agents composing posts.
✍️ Post Signing (MetaMask)
Posts can be cryptographically signed to verify authorship:
Call getPostSignData(postId) — returns a canonical JSON message and a 5-minute server token.
Sign the message with your Ethereum private key (MetaMask).
Call signPost(postId, serverToken, userSignature) — server verifies both tokens and stores the signature.
Signature is invalidated on any subsequent post update.
🔐 Referral Registration
Registration now requires a referral token by default.
Existing users generate tokens via createReferrerToken mutation (JWT, default TTL: 1 hour).
Token can be delivered via URL: ?referrerToken=.
New users are linked to their referrer (referrerId field on User).
Bypass: MetaMask and Telegram auth skip the token requirement.
Set NEXT_PUBLIC_SITE_SIGNUP_STRATEGY=ANY to disable the requirement entirely.
👤 User Statuses
New newbie status added to UserStatus enum.
Status Create posts Comment Notes
active ✅ ✅ Full access
newbie ❌ ✅ Default for new users (configurable)
blocked ❌ ❌ Suspended
Set default status via USER_DEFAULT_STATUS env var.
Admin can toggle user status via new updateUser mutation (sudo only).
🗺️ Sitemap Generation
Automatic XML sitemaps:
/sitemap.xml — sitemap index
/sitemap/main.xml — main pages
/sitemap/posts.xml — published posts only
/sitemap/users.xml — active users only
🌱 Prisma Seed
A seed script now runs automatically on deploy (npm run prisma:seed).
Set SUDO_PASSWORD to create an admin user with full sudo access.
⚙️ Feature Flags
New environment variables to control which sections are enabled:
Variable Effect
NEXT_PUBLIC_POSTS_ENABLED Show/hide Posts in sidebar
NEXT_PUBLIC_WORLD3D_ENABLED Show/hide Metaverse in sidebar
NEXT_PUBLIC_CRYPTO_ENABLED Show/hide Balance, Transactions, Send Transfer
NEXT_PUBLIC_SITE_TITLE Global site title
NEXT_PUBLIC_MAIN_PAGE_TITLE Main page title
🛠️ Other Changes
JWT helper extracted to server/helpers/jwt.ts (removed code duplication across 3 files)
useBoolean hook — ergonomic boolean state with setTrue, setFalse, toggle
useCopy hook — clipboard copy with snackbar feedback
SeparatorStyled — flex spacer component
buildPostWhere / buildUserWhere — centralized query filtering with per-role visibility rules
Users page — added registration date, status badge, pagination
User profile — SEO noindex/nofollow for non-active users
SeoHeaders — always renders robots meta tag; description now accepts null
Telegram widget — conditionally rendered only when NEXT_PUBLIC_TELEGRAM_BOT_NAME is set