Build Autonomous AI Agents in OpenClaw (with TypeScript Examples)

Jayesh Jain

Feb 13, 2026

11 min read

Share this article

Build Autonomous AI Agents in OpenClaw (with TypeScript Examples)

“Autonomous AI agents” sounds like a buzzword until you ship one that quietly saves you hours every week. The core loop is straightforward:

  • Watch for something important (new email, a tech update, a failing container)
  • Think (classify, plan, decide what to do next)
  • Act (draft a reply, suggest a post, generate code, propose a fix)
  • Learn/remember (store decisions, avoid repeat work, keep an audit trail)

OpenClaw is a strong fit for this because it’s built like a personal operations layer: it can schedule recurring tasks (cron), react to events (hooks/webhooks), and deliver output to real channels (Telegram/WhatsApp/etc.).


What you’ll build in this post

  1. A dedicated Trends Agent with its own workspace + SOUL.md
  2. An hourly cron job that produces: 5 tech updates + sources + 3 tweet drafts + optional thread
  3. Telegram delivery (draft-only; no auto-posting)

What “autonomous” should mean (in production)

Autonomy is a spectrum. In real systems, the best agents are usually:

  1. Semi-autonomous by default: the agent drafts actions and asks for approval.
  2. Fully autonomous only for low-risk tasks: housekeeping, summaries, formatting, routine checks.
  3. Auditable: every action is logged and reversible when possible.
  4. Bounded: strict scope, explicit tools, and clear stop conditions.

A useful mental model is: agent = policy + tools + schedule + guardrails.


Agent set #1: Email agent (read → draft response)

Goal

  • Detect new emails (support inquiries, sales leads, vendor messages).
  • Classify urgency + topic.
  • Draft a reply in your voice with the right context.
  • Start with draft-only. Don’t auto-send on day one.
  • Don’t open attachments automatically.
  • For password resets, billing changes, refunds, legal requests: always escalate.

Agent set #2: Latest tech updates → tweet suggestions (hourly)

Goal

  • Track latest tech updates (AI, developer tooling, cloud, security, OSS releases).
  • Turn them into tweet drafts for X.com.
  • Deliver drafts to Telegram for quick review.

Guardrails

  • No confidential info.
  • Avoid unverifiable claims; include sources.
  • Draft-only: do not auto-post.

Agent set #3: Code snippet agent (prompt → generate → validate)

Goal

  • Generate correct code snippets (TypeScript utilities, API handlers, Dockerfiles).
  • Provide usage examples and edge cases.

Agent set #4: Docker ops agent (observe → report → optionally fix)

Goal

  • Identify disk usage (images, volumes, logs).
  • Detect unhealthy containers and repeated restarts.
  • Propose safe cleanups; require approval for destructive actions.

If you want your hourly trend/tweet automation to have a different personality and scope than your main assistant, set up a separate agent workspace.

Step 1 - Create a new agent workspace folder

Example (inside your existing OpenClaw workspace mount):

1mkdir -p /mnt/openclaw-workspace/trends-agent/memory 2cp /mnt/openclaw-workspace/AGENTS.md /mnt/openclaw-workspace/trends-agent/AGENTS.md 3cp /mnt/openclaw-workspace/USER.md /mnt/openclaw-workspace/trends-agent/USER.md 4cp /mnt/openclaw-workspace/TOOLS.md /mnt/openclaw-workspace/trends-agent/TOOLS.md

Create:

1nano /mnt/openclaw-workspace/trends-agent/SOUL.md

Keep it focused. Example rules:

  • mission: find latest tech updates + draft X.com posts
  • must include sources
  • draft-only (never auto-post)

What these agent files are for (SOUL.md, AGENTS.md, USER.md, etc.)

OpenClaw agents don’t “remember” anything unless it’s written down. These files are how you give an agent a stable identity, rules, and continuity.

SOUL.md - persona + behavior rules

The agent’s operating system: tone, boundaries, priorities, what to do/avoid.

AGENTS.md - how the workspace should be run

A workspace playbook: what to read first, safety conventions, and how to operate day-to-day.

TOOLS.md - environment-specific notes

Local facts needed to operate reliably (paths, ports, hostnames). Keep secrets out unless you explicitly want them stored.

USER.md - the human profile (how to help you)

Your preferences (tone, timezone, style) and current goals.

IDENTITY.md - name/emoji/avatar metadata

Optional, but helpful when you run multiple agents so it’s obvious who is who.

MEMORY.md - curated long-term memory

High-signal, stable context (decisions, preferences, long-lived facts).

memory/YYYY-MM-DD.md - daily logs / journal

Raw daily notes. Later, promote important items into MEMORY.md.


If you want a working example you can paste straight into files, here are minimal templates aligned to the hourly tech updates → X.com drafts → Telegram delivery workflow.

1# SOUL.md - Trends Agent 2 3Mission: 4- Every hour, find credible tech updates and draft X.com tweets. 5 6Rules (non-negotiable): 7- Always include sources/links. 8- No unverifiable claims. If unsure, say "unclear" or skip. 9- Draft-only: never auto-post to X.com. 10- Keep tweets <= 280 characters. 11 12Style: 13- Practical, builder-focused, slightly opinionated. 14- Short sentences. No hype. 15 16Output format: 171) 5 updates + links 182) best pick + why 193) Tweet A/B/C 204) optional 4-tweet thread

AGENTS.md (workspace playbook)

1# AGENTS.md (Trends workspace) 2 3## Every session 41) Read SOUL.md, USER.md, latest daily memory. 52) Stay in scope: tech updates + X.com drafts only. 6 7## Safety 8- Never run destructive commands. 9- Never post automatically. 10- Prefer reversible actions.

USER.md (preferences)

1# USER.md 2 3- Name: Jayesh Jain 4- Timezone: UTC (or set your local TZ) 5- Posting style: crisp, practical, no fluff 6- CTA preference: only when relevant ("Read more", "Try it", etc.)

TOOLS.md (where/how to deliver)

1# TOOLS.md 2 3### Telegram 4- Primary destination: telegram:<your_chat_id> 5 6### X.com 7- Posting: manual only (drafts delivered to Telegram)

IDENTITY.md (optional)

1# IDENTITY.md 2 3- Name: Trends Agent 4- Creature: Scout 5- Vibe: concise, evidence-driven 6- Emoji: 🛰️

MEMORY.md (curated long-term rules)

1# MEMORY.md 2 3## Writing rules 4- Avoid hashtags unless essential. 5- Prefer one strong insight per tweet. 6 7## Topics to prioritize 8- AI agents, developer tooling, cloud infra, security advisories, notable OSS releases.

memory/YYYY-MM-DD.md (daily log example)

1# 2026-02-13 2 3- Picked: <best update> 4- Tweet chosen: Option B 5- Notes: audience liked practical benchmark angle

Edit ~/.openclaw/openclaw.json and add a second agent entry:

1{ 2 agents: { 3 list: [ 4 { id: "main", default: true, workspace: "/mnt/openclaw-workspace" }, 5 { id: "trends", name: "Trends Agent", workspace: "/mnt/openclaw-workspace/trends-agent" } 6 ] 7 } 8}

Restart the gateway after config changes:

1openclaw gateway restart

Step-by-step: Add an hourly “Latest Tech → X.com Tweet Suggestions” cron job (deliver to Telegram)

This section shows the exact cron job setup. It assumes:

  • Telegram bot is configured and you’ve paired/allowed your chat ID
  • your OpenClaw instance can retrieve web pages (via sandbox browser if you’re in Docker)

Step 1 - Create the cron job (every 1 hour)

1openclaw cron add \ 2 --name "Latest tech → X.com tweet suggestions (hourly)" \ 3 --every-ms 3600000 \ 4 --session isolated \ 5 --message "You are my tech news + X.com copy assistant.\n\nRun hourly:\n1) Find 5 latest notable tech updates from the last 24-48 hours (AI + dev tools + cloud + security + OSS).\n2) Include a source link for each.\n3) Pick the best ONE update to tweet about (explain why it’s most interesting/valuable).\n4) Draft 3 tweet options (each <= 280 chars) with different angles: (a) practical takeaway, (b) opinionated take, (c) mini-summary + what to do next.\n5) Provide an optional 4-tweet thread version.\n\nRules:\n- Draft-only. Do NOT post automatically.\n- No confidential info.\n- No unverifiable claims; if unsure, frame as opinion or ask for confirmation.\n- Output in plain text with clear separators." \ 6 --announce \ 7 --channel telegram \ 8 --to "telegram:<telegram_chat_id>"

Step 2 - Verify and test

1openclaw cron list 2openclaw cron run <job-id> 3openclaw cron runs --id <job-id>

Bind the job to agentId: "trends" so it runs with the Trends Agent’s SOUL.md and workspace.


TypeScript example: Turn a trend into an X.com post (draft + approval)

Below is a practical TypeScript pattern you can use inside your codebase to generate a tweet (or thread) from a selected trend, without auto-posting.

It’s intentionally split into two steps:

  1. Generate a draft tweet from a trend + source URL
  2. Human approval before anything is posted to X

1) Define the input + output

1type TrendItem = { 2 title: string; 3 url: string; 4 bullets: string[]; // 2-5 key facts 5}; 6 7type TweetDraft = { 8 bestPickWhy: string; 9 tweetOptions: { 10 style: "practical" | "opinionated" | "summary"; 11 text: string; // <= 280 chars 12 }[]; 13 thread?: string[]; // each tweet <= 280 chars 14};

2) Generate tweet drafts from a trend (LLM call)

1interface LlmClient { 2 complete(opts: { 3 system: string; 4 user: string; 5 temperature?: number; 6 }): Promise<string>; 7} 8 9const SYSTEM = ` 10You write X.com drafts for a tech audience. 11Rules: 12- Output JSON only. 13- Every claim must be supported by the provided bullets. 14- Each tweet must be <= 280 characters. 15- No hashtags unless they add real value. 16- Draft-only: do not instruct posting automation. 17`.trim(); 18 19export async function draftTweetsFromTrend(llm: LlmClient, trend: TrendItem): Promise<TweetDraft> { 20 const user = ` 21Trend: 22- Title: ${trend.title} 23- Source: ${trend.url} 24- Facts:\n${trend.bullets.map((b) => `- ${b}`).join("\n")} 25 26Task: 271) Explain why this is the best trend to tweet today. 282) Draft 3 tweet options (practical/opinionated/summary). 293) Provide an optional 4-tweet thread. 30 31Return JSON matching TweetDraft. 32`.trim(); 33 34 const raw = await llm.complete({ system: SYSTEM, user, temperature: 0.4 }); 35 return JSON.parse(raw) as TweetDraft; 36}

3) Approval loop (example)

Your cron job can deliver the drafts to Telegram. You reply with:

  • “Use option #2”
  • “Rewrite option #1 more technical”

Only after that should you post to X (manual is safest to start).


Common failure mode: no web retrieval (especially in Docker)

If the agent can’t browse/search, it should refuse to invent sources.

When running OpenClaw in Docker, the recommended fix is the sandbox browser:

  • Build the browser sandbox image:
1scripts/sandbox-browser-setup.sh
  • Enable it:
1{ 2 agents: { 3 defaults: { 4 sandbox: { browser: { enabled: true, autoStart: true } } 5 } 6 } 7}
  • Restart:
1openclaw gateway restart

A practical TypeScript example: “Autonomous Email Draft Agent”

Below is a practical TypeScript agent skeleton that demonstrates the pattern:

  • fetch work items (new emails),
  • run an LLM step to classify + draft,
  • output structured results you can route to a chat surface.

Note: the exact OpenClaw SDK/API surface depends on your deployment. Treat this as an application-level pattern you can run inside an OpenClaw isolated job.

Types + prompt discipline (structured output)

1// email-agent.ts 2type EmailMessage = { 3 id: string; 4 from: string; 5 subject: string; 6 receivedAt: string; // ISO 7 text: string; 8}; 9 10type DraftResult = { 11 emailId: string; 12 urgency: "low" | "medium" | "high"; 13 category: "sales" | "support" | "billing" | "partnership" | "unknown"; 14 summaryBullets: string[]; 15 draftSubject: string; 16 draftBody: string; 17 questionsForHuman?: string[]; 18 safeToAutoSend: boolean; 19}; 20 21const SYSTEM_POLICY = ` 22You are an assistant that drafts email responses. 23Rules: 24- Never claim you performed actions you didn't do. 25- If the email requests credentials, payment changes, refunds, or legal statements: set safeToAutoSend=false and add questionsForHuman. 26- Keep tone professional, concise, helpful. 27- Output MUST be valid JSON matching the DraftResult type. 28`.trim(); 29 30function buildUserPrompt(email: EmailMessage) { 31 return ` 32Email: 33From: ${email.from} 34Subject: ${email.subject} 35ReceivedAt: ${email.receivedAt} 36 37Body: 38${email.text} 39 40Task: 411) Classify urgency + category 422) Summarize in 2-5 bullets 433) Produce a reply draft (subject + body) 444) Ask clarifying questions if needed 455) Set safeToAutoSend=false unless it's a trivial acknowledgement. 46`.trim(); 47}

LLM call (provider-agnostic pattern)

1interface LlmClient { 2 complete(opts: { 3 system: string; 4 user: string; 5 temperature?: number; 6 }): Promise<string>; 7} 8 9function safeJsonParse<T>(raw: string): T { 10 const first = raw.indexOf("{"); 11 const last = raw.lastIndexOf("}"); 12 if (first === -1 || last === -1) throw new Error("No JSON object found."); 13 return JSON.parse(raw.slice(first, last + 1)); 14} 15 16export async function draftRepliesForEmails(opts: { 17 llm: LlmClient; 18 emails: EmailMessage[]; 19}): Promise<DraftResult[]> { 20 const results: DraftResult[] = []; 21 22 for (const email of opts.emails) { 23 const raw = await opts.llm.complete({ 24 system: SYSTEM_POLICY, 25 user: buildUserPrompt(email), 26 temperature: 0.3, 27 }); 28 29 const parsed = safeJsonParse<DraftResult>(raw); 30 31 // Hard guardrail: never allow auto-send initially. 32 parsed.safeToAutoSend = false; 33 34 results.push(parsed); 35 } 36 37 return results; 38}

Share this article

Inspired by This Blog?

Join our newsletter

Get product updates and engineering insights.

JJ

Jayesh Jain

Jayesh Jain is the CEO of Tirnav Solutions and a dedicated business leader defined by his love for three pillars: Technology, Sales, and Marketing. He specializes in converting complex IT problems into streamlined solutions while passionately ensuring that these innovations are effectively sold and marketed to create maximum business impact.

Want to ship agent automations fast?

I can help you design and deploy OpenClaw agents for support, ops, sales, and content workflows-securely and maintainably.

Let’s Talk

Related Posts