Skip to content

Aye Robot / Crusty — X automation (historical pause + unpause plan)

Field Value
Status Aye Robot gate unlocked (2026-04-27): image + Telegram + brainstorm → pick → approve → xurl live post to X verified E2E. Steady-state transport: xurl + OpenClaw skills/xurl/SKILL.md. 2026-04-29: Model routing rollback on Crusty (grok-4-1-fast-reasoning primary; grok-4.20 orchestrator paused — token economics); daily Telegram job tweak for consistent images. Next concrete step: mentions listen path (scheduled xurl/API readTelegram digest → optional Telegram-gated xurl reply) — canonical spec: projects/ayerobot-comic#next-concrete-step--mentions-listen-path. In parallel (~1 week): post path reliability. Routing history: projects/crusty (Model routing + Steady-state economics). Historical: 2026-04-18 pricing unblock.
Scope Autonomous daily comic loop on dedicated Mac (Crusty): @ayerobotcomic
Co-priority with projects/operator-agent — the two share Crusty's stack in non-conflicting ways (operator = ops skills, aye robot = post/listen skills).

Canonical detail for why the full agent loop stopped short of unattended X posting via consumer web, and how it unblocked onto X API v2 + OpenClaw skills. Published comic workflow and agent stack overview: projects/ayerobot-comic, projects/crusty. Next concrete build after gate unlockNext concrete step — mentions listen path on projects/ayerobot-comic. Cross-cutting debug patterns: recurring-issues (tool adapter, credential / key sources, session JSONL vs gateway logs).

2026-04-21: Unpause — E2E unblocked (Crusty host)

State (2026-04-21 history): Unblocked for image + bring-up X script. Steady state (2026-04-27): X posting is xurl + skills/xurl/SKILL.md (OAuth 2.0 PKCE, dev app) — not post_comic_test.py. Image generation works (workspace grok-imagine skill calling xAI grok-imagine-image). post_comic_test.py remains reference / archive (OAuth 1.0a from .env). Crusty runs the full pipeline (ideas → pick → Telegram gate → xurl post); see Status table and Still open above.

What we fixed (in order)

# Problem Root cause Fix
1 Config rejected by gateway Invalid JSON (missing braces, wrong nesting) Rewrote tail of ~/.openclaw/openclaw.json to valid JSON
2 Config rejected by schema x_api is not a recognized top-level key in OpenClaw's schema Removed x_api from JSON; X credentials live only in ~/.openclaw/.env
3 Gateway reload failures Stale grok-imagine-image entry under models.providers.xai.models with perImage / output keys the schema rejects Removed the image model entry — xAI image gen does not use the models path
4 image_generate tool failing imageGenerationModel.primary pointed at a non-existent xAI backend Removed imageGenerationModel entirely (OpenClaw only registers comfy / fal / google for that hook)
5 Skill looked “not working” when Crusty tried Crusty used compound shell (cd X && python3 Y && ls Z); OpenClaw exec preflight rejects compound commands SKILL.md: absolute-path single-command example + explicit “no cd && chaining” rule
6 SKILL.md helper path wrong Text pointed at ~/.openclaw/skills/ Actual install: ~/.openclaw/workspace/skills/
7 Crusty truncating responses mid-output xAI API key throttled at 60 TPM Raised to 10M TPM / 1,800 RPM at console.x.ai
8 post_comic_test.py broken after removing x_api from JSON Old loader required a JSON block .env fallback: reads the four X_* vars directly
9 comic.json / short-comic.json corrupted Bad patch: unknown command field, missing } Restored to valid {prompt, n} — prompt carriers, not flow definitions
10 projects.md one physical line with literal \n Earlier tool serialization bug Expanded escape sequences to real newlines
11 Crusty reached for image_generate instead of grok-imagine for the daily comic No durable instruction in loaded context Documented pipeline in workspace projects.md (Aye Robot), tool rule in TOOLS.md (Image Generation), breadcrumb in MEMORY.md

Image generation — working pattern (Crusty)

  • Location: ~/.openclaw/workspace/skills/grok-imagine/ (workspace-scoped; appears in openclaw skills list).
  • Invocation (Crusty — one direct command, no shell chaining):
    python3 ~/.openclaw/workspace/skills/grok-imagine/generate_image.py "PROMPT"
  • Auth: XAI_API_KEY in process environment, populated from ~/.openclaw/.env.
  • Output: .jpg under ~/.openclaw/media/outbound/ with a grok_imagine_<timestamp>_1.jpg name; stdout shows ✅ Saved: with the absolute path.
  • Mechanism: POST https://api.x.ai/v1/images/generations, model grok-imagine-image, download URL to disk.

Rule: Use grok-imagine, not OpenClaw's image_generate tool, for this comic pipeline.

What lives where (Crusty host)

Path Role
~/.openclaw/openclaw.json Clean JSON: no x_api, no imageGenerationModel; text models under xAI only
~/.openclaw/.env Secrets: XAI_API_KEY, X_CONSUMER_KEY, X_CONSUMER_KEY_SECRET, X_ACCESS_TOKEN, X_ACCESS_TOKEN_SECRET
~/.openclaw/workspace/skills/grok-imagine/ Image-gen skill + fixed SKILL.md
~/.openclaw/workspace/projects.md Full Aye Robot pipeline (ideas → pick → prompt → grok-imagine → reply; no auto-post)
~/.openclaw/workspace/TOOLS.md Rule: grok-imagine, never image_generate, single command only
~/.openclaw/workspace/MEMORY.md Breadcrumb to projects.md + TOOLS.md
~/.crusty/post_comic_test.py Standalone X poster; reads creds from .env; supports --dry-run

Still open (separate from core unpause)

  • Crusty model routing — two-tier live; Phases 3–4 complete (2026-04-27). projects/crusty Model routing. Optional Phase 5 sub-tier (non-reasoning for digests) still deferred.
  • Posting transport: xurl + skills/xurl/SKILL.mdlive (first E2E post 2026-04-27). post_comic_test.py = bring-up / reference.
  • Image scheduling: LIVE 2026-04-27 — morning cron → Telegram with a fresh grok-imagine panel.
  • X-post + gate: Livecaption + image (or equivalent package) to Telegram → manual approvalxurl; proven same day as gate unlock.
  • Live X post: Shipped on the xurl path (2026-04-27). Next: mentions listen path (see projects/ayerobot-comic#next-concrete-step--mentions-listen-path); post-path reliability in parallel (~1 week).
  • Wiki / handoff: This projects-wiki repo is now aligned with the above; any other copy of the old model (e.g. stale notes with x_api in JSON or image_generate for images) should be updated before handoff.

2026-04-21: Next steps — switch transport to xurl (X's official CLI)

Why xurl over post_comic_test.py: the Python script was a bring-up tool that proved credentials + policy + pricing shape in dry-run. The steady-state transport should be the CLI X itself ships — no homemade OAuth plumbing to babysit, native media upload, natural-language surface through OpenClaw's already-merged skills/xurl/SKILL.md (Crusty auto-recognizes it). No Playwright, no custom script maintenance, no third-party bridges.

Confirmed prerequisites (as of 2026-04-21):

  • Dev app exists on the band X account. Client ID + Client Secret issued, package set to Pay-per-use, environment set to Production — both of these are required or xurl calls will 401 with client-forbidden. (reference tweet)
  • Target post account: @ayerobotcomic (the handle the comics actually publish from).
  • Crusty isolation preserved: no personal creds, no this-repo access, xAI/Grok-only model stack, Telegram approval gate carries over.
  • Comic format unchanged: single-panel sci-fi humor image (grok-imagine skill) + caption; image leg on a morning schedule to Telegram (2026-04-27); post leg via xurl after Telegram approval live (2026-04-27).

Handoff steps (run the auth steps manually on Crusty — do not let the agent handle secrets):

  1. ~~Prerequisite — Crusty model routing Phases 3–4.~~ Complete 2026-04-27 per projects/crusty Model routing — two-tier live; Aye Robot gate unlocked (E2E Telegramxurl). Treat this step as historical for new installs; do not re-sequence a live post before routing on a fresh machine.
  2. ~~Install xurl on Crusty (one-time, terminal) — done 2026-04-27.~~ Original steps kept for new-machine / disaster recovery:
  3. Preferred on the dedicated macOS laptop: brew install --cask xdevplatform/tap/xurl
  4. Cross-platform alternative: npm install -g @xdevplatform/xurl
  5. One-liner fallback: curl -fsSL https://x.dev/xurl/install | bash
  6. ~~Authenticate (OAuth 2.0 PKCE) — done 2026-04-27.~~ Original flow for rebuilds:
  7. Register the app: xurl auth apps add ayerobot-app --client-id <CLIENT_ID> --client-secret <CLIENT_SECRET>
  8. Start OAuth 2.0 flow (opens a browser): xurl auth oauth2
  9. Verify: xurl auth status
  10. Optional convenience: xurl auth default ayerobot-app
  11. ~~Smoke-test in terminal first — done 2026-04-27.~~ For verification after reinstall:
  12. xurl whoami → should return @ayerobotcomic.
  13. xurl timeline -n 3 → confirms read path.
  14. xurl post "Test from Crusty xurl — ignore this"first live tweet; verify it actually appears on the profile.
  15. ~~Restart OpenClaw gateway / agent~~ (done 2026-04-27 when xurl path went live) — on rebuild: so it picks up the local xurl binary and the merged skills/xurl/SKILL.md.
  16. ~~Update the daily Aye Robot prompt~~ (done 2026-04-27) — use xurl end-to-end (natural language; the skill handles the subcommands):
  17. Generate today's panel with grok-imagine (single-panel sci-fi sarcasm, newspaper-cartoon style); save as ~/.openclaw/media/outbound/aye-robot-YYYY-MM-DD.jpg.
  18. Draft caption.
  19. Send image + caption to Telegram for human approval.
  20. On approval, post via xurl — e.g. xurl post "[full caption] #AyeRobotComic" --media ~/.openclaw/media/outbound/aye-robot-YYYY-MM-DD.jpg (check skills/xurl/SKILL.md for the exact media flag — the skill abstracts media upload).
  21. Capture the returned post URL / ID; log success (and optionally xurl read <post-id> or a xurl timeline -n 1 to verify).
  22. Next concrete step (2026-04-27) — Wire the mentions listen path: scheduled read (xurl / GET /2/users/{id}/mentions / xurl search as appropriate) → Telegram digest to Darcy → optional draft replyxurl reply only after the same Telegram human-gate as the comic post. Canonical numbered spec: projects/ayerobot-comic#next-concrete-step--mentions-listen-path. (The X-post + grok-imagine + approval post path is live; image morning cron is live — see Status above.)

What this retires:

  • ~/.crusty/post_comic_test.pydemoted to bring-up / archive reference (first live xurl post shipped 2026-04-27). Credentials it reads (X_CONSUMER_KEY / X_CONSUMER_KEY_SECRET / X_ACCESS_TOKEN / X_ACCESS_TOKEN_SECRET in ~/.openclaw/.env) can stay in place — they're independent of xurl's OAuth 2.0 token store — but they're not the steady-state posting path. Don't build new skills on top of them.
  • The old "write our own media-upload wrapper" branch of the plan — xurl handles v2 media upload natively; v2 media-upload pricing is still a standing open question (below), but the mechanism no longer needs custom code.

Why this is cleaner than the prior path:

  • Official, supported, local: xurl is X's own CLI; no third-party bridge, no scraping, no browser.
  • OpenClaw already recognizes it: skills/xurl/SKILL.md is merged upstream, so Crusty gets a natural-language surface (xurl post, xurl reply, xurl search, xurl timeline) without us writing a skill.
  • Pay-per-use pricing unchanged: ~$0.015 / text post, ~$0.001 / owned read, ~$1.20/mo at current cadence.
  • Policy posture unchanged: still API v2, still inside X's automation "Do" examples (image-only, image-only lead post, human-gated replies).

Goal

Autonomous daily comic loop on a dedicated Mac (Crusty): generate image (xAI) → Telegram approval → post to X (@ayerobotcomic) → monitor replies. Stack is OpenClaw (agent / gateway), xAI-only models per project constraints.

What is verified and working

  • OpenClaw workspace and tooling on the host: agent workspace and skills area healthy; image / memory / media directories in place. 2026-04-21: Workspace grok-imagine skill is the supported image path for the comic (not OpenClaw's built-in image_generate). Paths on the Crusty machine: see What lives where above.
  • xAI API: Authentication and calls validated (direct /v1/models, assistant turns). Key-sourcing pattern (actual, confirmed 2026-04-20): xAI and X secrets live in Crusty's ~/.openclaw/.env; OpenClaw JSON stays schema-clean (no top-level x_api). Config may reference vars via ${env:VAR} where applicable — not duplicated into shell profile files (.zshrc / .bash_profile). → recurring-issues (key / env sprawl — aspirational-vs-actual resolution).
  • Shell / exec tool: Confirmed real subprocess execution via the agent's session-log audit trail — look for exec-tool entries with exit code and duration. Do not rely on the gateway log for shell proof; the session log is the audit trail. Exec constraint: OpenClaw rejects compound shell commands — skills and docs must use one absolute-path command (no cd && chains). → recurring-issues (gateway log ≠ ground truth).
  • Image generation (comic): grok-imagine skill → POST xAI Images API (grok-imagine-image), files land under ~/.openclaw/media/outbound/. Do not route this through models.providers.xai.models or imageGenerationModel — those paths do not apply to xAI image gen on this stack.
  • X API posting (steady state): X's official xurl CLI + OpenClaw's merged skills/xurl/SKILL.mdOAuth 2.0 PKCE with the dev app; install + auth + first live post complete 2026-04-27 — see Next steps — switch transport to xurl. Bring-up script (historical): ~/.crusty/post_comic_test.py — OAuth 1.0a, X_* from .env; was dry-run + bring-up only.
  • Telegram: Bot/channel wired through OpenClaw config; generate → Telegram → approve → xurl post path live (2026-04-27). Next build = mentions listen path (see Still open / Status).
  • Local automation sandbox: Separate local sandbox directory (Python venv, browser profile, logs, skills), Playwright + Chromium installed in venv — for non-X recon only; X transport is API-only.
  • Playwright smoke: Can launch the browser with persistent user-data dir and open pages; not used for @ayerobotcomic posting (policy + design).

Where it stalled (not reliable for autonomy yet)

Posting to X via browser automation (Playwright + Brave + consumer x.com UI) is not a stable foundation for a fully autonomous agent today — and as of the 2026-04-20 re-read of X's automation rules it is also explicitly prohibited:

  • Policy (hard stop): X's automation rules state "Don't use non-API-based automation like scripting the X website", and explicitly flag that doing so can result in permanent account suspension. This closes the browser-automation path as a design option, not just as an engineering one. @ayerobotcomic is a dedicated account with real follower count; a ban has no upside.
  • Engineering (why it was fragile anyway): X treats automated browsers harshly (login flows resetting, anti-bot behavior); "log in manually with plain Brave using the same profile" + "reuse cookies in Playwright" did not converge to a repeatable, unattended logged-in state; the "controlled by automated test software" surface is detectable and the mitigations are a moving target.

So: infrastructure for image + exec + Telegram is in good shape; unattended X posting through the web app is the weak link, not OpenClaw itself — and per X policy it can't be the transport regardless of how stable we made it.

Design decisions recorded

  • A local sandbox holds venv, browser profile, and future posting scripts; the agent-visible workspace holds OpenClaw-tracked skills. Kept deliberately separate.
  • JSON receipts on stdout, human trace on stderr for skills — for orchestration and postmortems.
  • Diagnostic habit: UI weirdness or dropped tool calls → check the gateway error log and auth before blaming the model.

If you resume later (high level)

  • X posting transport = X API only. Browser automation is policy-prohibited, not merely discouraged (see X automation rules). The only other permitted channels are manual human post or a different platform. Do not re-open the Playwright + consumer-web path.
  • Keep the agent's session-log audit trail as ground truth for whether tools actually ran.

2026-04-18: Unpause signal — X API pricing change

What changed (announced 2026-04-17, effective 2026-04-20):

  • No subscription gate. X API is now pay-per-use, credit-based, no Basic/Pro tier required — see X API pricing. Auto-recharge + spending limits available in the Developer Console.
  • Owned reads (own posts, mentions, followers, lists metadata, etc.): $0.001/request (1,000 for $1). Deduplicated within 24-hour UTC window.
  • Text post via POST /2/tweets: $0.015 (up from $0.01).
  • Post containing a URL: $0.20 per post (13x text). Summoned replies exempt at $0.01.
  • Removed from self-serve tier entirely: POST /2/users/{id}/following, POST /2/users/{id}/likes, quote-posts via quote_tweet_id.
  • xAI credit rebate: 10–20% of X API spend back as xAI credits if you link teams (Crusty already runs xAI-only, so this is pure upside).

Why this matters for this project: the specific blocker — "unattended X posting through the web app is the weak link" — goes away when transport moves to the API. Transport was the fragility; nothing else in the stack was broken.

Unblock path (Crusty → X API, no browser):

  1. Replace the browser-automation posting skill with an OpenClaw skill calling X API v2 (POST /2/tweets). Keep the Telegram approval gate unchanged — the gate is the human-in-the-loop safety net, not the transport.
  2. Auth model = OAuth 1.0a user-context (four keys), not Bearer Token. POST /2/tweets is a user-context endpoint — app-only Bearer tokens can't call it (Bearer only works on read-mostly endpoints that support app-only auth). For a single-handle daily posting loop, use the four OAuth 1.0a keys from the developer app's user-context credentials: API Key, API Key Secret, Access Token, Access Token Secret. OAuth 2.0 Authorization Code + PKCE is the alternative but adds a refresh-token dance that isn't worth it for a single-owner handle. Storage: all four go into Crusty's .env (same file the xAI key already lives in — see note above); the OpenClaw config references them via ${env:VAR} expansion. Reference implementation for this handoff: post_comic_test.py uses OAuth 1.0a user-context with env-sourced secrets. → recurring-issues (key / env sprawl, aspirational-vs-actual resolution).
  3. Image-attached posts via v2 media upload. Use POST /2/media/upload (v2) — v1.1 /media/upload still responds but the docs index now lists v1.1 media as legacy, so all new work should target v2. For anything that needs chunked / resumable upload, v2 exposes explicit routes: POST /2/media/upload/initializePOST /2/media/upload/:id/appendPOST /2/media/upload/:id/finalize. Reference the returned media_id from the post body when calling POST /2/tweets. Verify v2 media pricing before committing — the 2026-04-17 pay-per-use announcement covered POST /2/tweets but did not explicitly quote v2 media-upload pricing.
  4. Mentions polling via GET /2/users/{id}/mentions on an hourly cron is cheap (~$0.72/mo at 1/hr). Wire into Telegram for reply drafting. Optionally batch GET /2/tweets with tweet.fields=public_metrics on recent @ayerobotcomic ids a few times per day for an engagement rollup (same owned-read pricing) — projects/ayerobot-comic#post-engagement-metrics-poll.
  5. Leave the local sandbox (Playwright + browser + venv) installed but idle for non-X recon only. Do not revive the X browser-profile path — X's automation rules treat "scripting the X website" as a permanent-suspension offense.

Rough monthly cost at current cadence (1 comic/day + hourly mentions poll + optional post-metrics poll):

Line Volume Cost
Comic posts (image-only, no URL) 30 $0.45
Mentions poll, hourly 720 $0.72
Post metrics poll (e.g. 3/day, batched ids) ~90 $0.09
Own-timeline spot checks ~30 $0.03
Subtotal ~$1.29/mo
xAI rebate at $0 spend tier 0% $0

If comic posts link to anywhere (archive URL, band site, etc.), each such post costs $0.20 instead of $0.015 — that's $6/mo extra at daily cadence for the URL alone. Design implication: image-only primary post; put any link in a summoned reply ($0.01) or in the bio.

What the pricing change does NOT fix:

  • Growth patterns that relied on auto-like / auto-follow / quote-post are dead on self-serve. Growth strategy must shift to original-content-attracts-mentions + manual-gated replies. Reply-to-mentions is allowed at $0.01.
  • Content-policy risk unchanged. X can still suspend the account if posts look spammy; API access doesn't buy leniency. Keep Telegram approval gate in place — and per X automation rules, "account holders are ultimately responsible for automated activity on their accounts," which means the gate is now the policy-aligned design, not just a defensive one.
  • API terms/pricing can change again. Elon's history suggests the pricing now is not the pricing forever. Keep the posting skill abstracted enough to swap transports (to another platform entirely — not back to browser automation, which is policy-prohibited regardless of future API price hikes).

Open questions to resolve before full “daily unattended” operation:

  • [ ] v2 media upload pricing — is POST /2/media/upload (and the chunked initialize / append / finalize routes) in the owned-reads $0.001 bucket, separate, or bundled with the post? Check the rate card in Developer Console. Mechanism is now handled by xurl regardless; this is pure cost-model hygiene.

Closed (2026-04-21):

  • ~~Image generation upstream of posting~~ — Resolved: workspace grok-imagine skill + valid OpenClaw JSON/schema (see fix table above). ~~Scheduling + xurl live post~~ — Resolved 2026-04-27 (morning cron + E2E xurl after approval); not image capability.
  • ~~Dev-app provisioning~~ — Resolved: dev app already exists on the band X account with Client ID + Secret, Pay-per-use package, Production environment. (Pay-per-use + Production are both required; without them xurl errors with client-forbidden.) → See Next steps — xurl.

Closed (2026-04-20, by re-reading X automation rules):

  • ~~Is 1 image/day close enough to "normal human account behavior" that suspension risk is low?~~ — Yes. X's own rules list "Automatically broadcast helpful information in posts" as an allowed use case, alongside auto-replies to engaged users and DM auto-responders. A single image-only daily post + human-gated mentions reply is squarely inside the named "Do" examples, not gray-zone.

Decision rule (historical): the pricing + API path cleared the old Paused state. 2026-04-21: treat the project as Active on the stack (image + post script); finish scheduling, live smoke-test post, and any Telegram approval productization as separate checklist items.

Policy posture (2026-04-20, X automation rules)

Re-reading X's automation policy simplifies the project: the current design is explicitly inside the "Do" list and the tempting fallback is explicitly in the "Don't" list.

X rule Applies here as
Do: "Automatically broadcast helpful information in posts" Daily one-panel comic via X API v2 — named allowed use case.
Do: "Build solutions that automatically respond to users in Direct Messages" + "Run creative campaigns with auto-replies to engaged users" Mentions-polling + Telegram-gated reply workflow — allowed, no separate approval needed from X.
Don't: "Use non-API-based automation like scripting the X website" — can result in permanent account suspension Browser automation (Playwright / Brave consumer UI) is permanently off the table for @ayerobotcomic, not just paused. Combined with the 2026-04-17 pay-per-use pricing, API v2 is the only transport that is both economic and compliant.
Don't: spam / unsolicited messages 1 image/day, no cold DMs, no auto-follow, no auto-like, no quote-post farming. (Three of those four are also removed from self-serve API as of 2026-04-17, so this is belt-and-suspenders.)
"Account holders are ultimately responsible for automated activity on their accounts." Telegram approval gate is now policy-aligned, not just defensive design. Keeps Darcy in the loop for any state-changing action.
Restricted: off-X matching (linking X usernames to external identifiers requires explicit opt-in) Not in scope today. Guardrail if @ayerobotcomic ever builds analytics that join replies to external IDs.
Restricted: redistribution — use Post IDs, DM IDs, User IDs, not full content Guardrail for any future archive/mirror of comic replies.

Net effect on the unpause plan: one design option killed (browser automation — hard no, permanent), one open question closed (cadence is clearly compliant), the Telegram gate gets a stronger "why," and the rest of the 2026-04-18 plan (port to X API v2, reuse Telegram gate, hourly mentions poll, optional batched post-metrics reads) is unchanged and explicitly endorsed by policy.

Note on community

There is no requirement that “many OpenClaw users” ship X posting in autonomous loops. Browser-driving a consumer social network from an agent is inherently brittle; pausing to reconsider is reasonable and does not imply OpenClaw is unsuitable — only that this integration needs a different contract (API, human gate, or another channel).