forked from molecule-ai/molecule-core
Merge pull request #1262 from Molecule-AI/fix/sweeper-emit-provision-failed
fix(sweeper): emit WORKSPACE_PROVISION_FAILED so canvas updates UI
This commit is contained in:
commit
1f35128ebb
105
docs/blog/2026-04-21-skills-vs-bundled-tools/index.md
Normal file
105
docs/blog/2026-04-21-skills-vs-bundled-tools/index.md
Normal file
@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "Skills Over Bundled Tools: Why Composable AI Beats Platform Primitives"
|
||||
date: 2026-04-21
|
||||
slug: skills-vs-bundled-tools-ai-agent-platforms
|
||||
description: "Hermes v0.10.0 bundles 4 platform tools. Molecule AI installs them as skills. This piece explains why composability beats convenience for production multi-agent teams."
|
||||
tags: [skills, hermes, comparison, composability, AI-agents, tutorial]
|
||||
---
|
||||
|
||||
# Skills Over Bundled Tools: Why Composable AI Beats Platform Primitives
|
||||
|
||||
Hermes v0.10.0 launched Tool Gateway — a set of built-in tools (web search, image generation, TTS, browser automation) available to paid Portal subscribers. If you're evaluating AI agent platforms, you might see a feature list comparison that looks like this:
|
||||
|
||||
- **Hermes:** Has web search, image gen, TTS, browser automation — *out of the box*
|
||||
- **Molecule AI:** Doesn't seem to have these — *requires skill installation*
|
||||
|
||||
That reading is fair. It's also incomplete.
|
||||
|
||||
This piece explains what "skills" actually means on Molecule AI, why composability is structurally different from bundled tools, and how the two approaches serve fundamentally different use cases.
|
||||
|
||||
## What "Bundled Tools" Actually Means
|
||||
|
||||
Hermes Tool Gateway ships four capabilities as platform-level primitives. When you use them, you're using the same implementation every other Hermes user uses — same models, same rate limits, same behavior. You can't swap the image generator for a different one. You can't add a new tool to the bundle without a platform update.
|
||||
|
||||
**The appeal is real:** sign up, start using, no configuration. That's excellent for a personal productivity tool.
|
||||
|
||||
**The limitation is structural:** you get what's shipped. Your agent's capabilities are defined by what the platform vendor decided to include, and they don't change until the vendor ships an update.
|
||||
|
||||
## What "Skills" Actually Means
|
||||
|
||||
Skills on Molecule AI are installable capability packages — analogous to npm packages or pip modules, but for agent capabilities. A skill packages:
|
||||
|
||||
- **Tool definitions** — the JSON Schema interfaces the agent sees
|
||||
- **Runtime code** — the actual implementation (API calls, local processing, etc.)
|
||||
- **Configuration** — sensible defaults, required env vars, scoping rules
|
||||
- **Versioning** — install a specific version, upgrade when ready
|
||||
|
||||
The browser automation skill on Molecule AI isn't a different feature from Hermes' browser tool — it uses the same underlying technology (Chrome DevTools Protocol over WebSocket). The difference is *how you install it* and *what you can do with it*:
|
||||
|
||||
```bash
|
||||
# Install browser automation skill
|
||||
molecule skills install browser-automation
|
||||
|
||||
# Install TTS skill (alternative: use your own provider)
|
||||
molecule skills install tts --provider openai
|
||||
|
||||
# Install a community skill
|
||||
molecule skills install arxiv-research --from community
|
||||
```
|
||||
|
||||
After installation, your agent sees the tools the same way it sees any other tool — they're first-class in the agent's tool context. But unlike Hermes' bundled approach, you can:
|
||||
|
||||
- Swap the TTS provider (OpenAI → ElevenLabs → self-hosted)
|
||||
- Version-pin to a known-good skill release
|
||||
- Inspect the skill code (it's just Python)
|
||||
- Contribute a new or improved version back to the community
|
||||
- Run the same skill locally or on any cloud VM
|
||||
|
||||
## The Composability Difference
|
||||
|
||||
Bundled tools are a feature set. Skills are a *package manager*. The difference matters as your agent stack grows.
|
||||
|
||||
**With bundled tools:** you use what ships. If the image generator doesn't support a format you need, you file a feature request.
|
||||
|
||||
**With skills:** you combine what's available. Need a specialized tool that doesn't exist? Write a skill and install it. Someone else already built it? Install it with one command.
|
||||
|
||||
The skills ecosystem on Molecule AI already covers the same ground as Hermes Tool Gateway — browser automation, TTS, image generation, web search — plus dozens of additional capabilities contributed by the community. You start from zero by default, which has higher first-run friction. But the ceiling is open.
|
||||
|
||||
## The Production Trust Angle
|
||||
|
||||
For **individual developers**, bundled tools win on first-impression convenience. For **production teams**, the calculus is different.
|
||||
|
||||
When you deploy an agent in production, you need to answer:
|
||||
|
||||
- *Who has access to which tools?* (auth)
|
||||
- *Which pipeline used which tool?* (audit)
|
||||
- *Can I revoke access without a redeploy?* (operations)
|
||||
|
||||
Hermes Tool Gateway is designed for personal Portal accounts — there's no org-level auth, no per-user scoping, no audit trail across a team.
|
||||
|
||||
Molecule AI's skills run inside workspaces, which means they inherit the full access control model:
|
||||
|
||||
- **Org-scoped API keys** — name, revoke, and audit every integration independently
|
||||
- **Workspace-level secrets** — per-agent credential management, no shared tokens
|
||||
- **Audit trail** — `org:keyId` on every request, chain of custody from minting to use
|
||||
|
||||
If you're evaluating a platform for a team, the question isn't just "does it have tools?" — it's "can I trust those tools in a production context?" Molecule AI's answer to that question is the skills ecosystem *plus* the auth layer that surrounds it.
|
||||
|
||||
## The Unified Narrative
|
||||
|
||||
Here's how the comparison lands:
|
||||
|
||||
> **Hermes** is a personal AI assistant — batteries included, no auth model, no team features.
|
||||
>
|
||||
> **Molecule AI** is a platform your team can build on, ship to customers, and trust in production — with skills for every capability Hermes bundles, org-level auth, and audit on every call.
|
||||
|
||||
If you want to evaluate Molecule AI's skills coverage, start here:
|
||||
|
||||
→ [MCP browser automation guide](/docs/blog/browser-automation-ai-agents-mcp) — browser tools via Chrome DevTools Protocol, same capability as Hermes' built-in browser
|
||||
→ [TTS and image generation skills](/docs/guides/skill-catalog) — community-contributed, versioned, swappable
|
||||
→ [Org-scoped API keys](/docs/guides/org-api-keys.md) — production auth and audit
|
||||
|
||||
**The tagline:** Batteries included is nice. Batteries you can trust, extend, and audit is a platform.
|
||||
|
||||
---
|
||||
*Skills are how Molecule AI delivers the same capabilities as Hermes Tool Gateway — with more flexibility, more control, and a production trust model built in. Browse the full skill catalog on GitHub or install directly via the CLI.*
|
||||
@ -1,6 +1,6 @@
|
||||
# MCP Server Setup Guide
|
||||
|
||||
The Molecule AI MCP server lets any MCP-compatible AI agent (Claude Code, Cursor, etc.) manage workspaces, agents, secrets, memory, schedules, channels, and more through the platform API.
|
||||
The Molecule AI MCP server lets any MCP-compatible AI agent manage workspaces, agents, secrets, memory, schedules, channels, and more through the platform API. It works with Claude Code, Cursor, and any other tool that speaks the MCP protocol.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
# Chrome DevTools MCP — Backlinks Outreach Draft
|
||||
Campaign: chrome-devtools-mcp-seo | Blog: docs PR #49 (merged `2026-04-20-chrome-devtools-mcp`)
|
||||
Status: Draft — Marketing Lead approval required before sending
|
||||
Date: 2026-04-21
|
||||
|
||||
---
|
||||
|
||||
## About backlinks
|
||||
|
||||
Backlinks (inbound links from other sites) improve SEO authority for the target keyword. For `MCP browser automation` and `browser automation AI agents`, the goal is placements in communities where AI agent developers and browser automation practitioners congregate.
|
||||
|
||||
Outreach should focus on communities that:
|
||||
- Discuss AI agent frameworks (LangChain, CrewAI, AutoGen, etc.)
|
||||
- Work on browser automation (Puppeteer, Playwright)
|
||||
- Build with the MCP protocol
|
||||
- Write about AI agent governance and security
|
||||
|
||||
Do NOT cold spam. Only reach out to communities where there's a genuine topical overlap. Personalize the message to the specific thread or context.
|
||||
|
||||
---
|
||||
|
||||
## Community outreach templates
|
||||
|
||||
### Reddit — r/programming / r/MachineLearning / r/artificial
|
||||
|
||||
**When:** A thread asks "how do I add browser automation to my AI agent?" or similar
|
||||
**Subject:** not applicable (Reddit DMs or comments)
|
||||
**Template (comment, not DM):**
|
||||
|
||||
> This is a genuinely hard problem — most agent platforms give you the browser access but not the governance layer. We wrote up how Molecule AI handles it with Chrome DevTools MCP: https://docs.molecule.ai/blog/chrome-devtools-mcp
|
||||
>
|
||||
> The short version: every browser action is logged with org API key attribution, sessions are token-scoped per agent, and revocation is instant. Makes it auditable to a security team that wasn't in the room when you configured it.
|
||||
>
|
||||
> Not claiming it's the only way to do it — but the governance angle seems to be the gap most platforms skip.
|
||||
|
||||
---
|
||||
|
||||
### Reddit — r/webdev / r/webdesign
|
||||
|
||||
**When:** A thread about automated browser testing or Lighthouse audits in CI/CD
|
||||
**Template (comment):**
|
||||
|
||||
> If you're running Lighthouse in a CI pipeline, worth looking at how agents can run it too — Molecule AI has an example of wiring Lighthouse into Chrome DevTools MCP so an agent can report scores automatically: https://docs.molecule.ai/blog/chrome-devtools-mcp
|
||||
>
|
||||
> The useful part for a team: the governance layer means your security team can see what the agent accessed, even in a CI context.
|
||||
|
||||
---
|
||||
|
||||
### LinkedIn — AI agent developers / platform engineers
|
||||
|
||||
**Template (connection note or comment on relevant post):**
|
||||
|
||||
> Saw your write-up on [specific post topic] — solid points on [specific detail].
|
||||
>
|
||||
> Molecule AI just shipped an MCP governance layer for Chrome DevTools that might be relevant to what you're working on: https://docs.molecule.ai/blog/chrome-devtools-mcp
|
||||
>
|
||||
> The angle we hear most often: browser automation for agents works fine until your security team asks "which agent accessed what, when, and can you prove it?" That's what the governance layer is for.
|
||||
>
|
||||
> Happy to chat through the approach if it's useful.
|
||||
|
||||
---
|
||||
|
||||
### MCP GitHub — modelcontextprotocol/servers
|
||||
|
||||
**When:** A discussion or PR about browser automation tools in MCP servers
|
||||
**Template (comment):**
|
||||
|
||||
> Related to how this might fit into the broader MCP ecosystem — Molecule AI's implementation of Chrome DevTools MCP adds org API key attribution at the platform level, so every MCP tool call through a browser action carries audit attribution: https://docs.molecule.ai/blog/chrome-devtools-mcp
|
||||
>
|
||||
> Would be useful to understand if there's appetite for a standard attribution field in the MCP tool response schema — seems like a natural fit for governance-oriented platforms.
|
||||
|
||||
---
|
||||
|
||||
### Hacker News / Lobsters
|
||||
|
||||
**When:** A thread about AI agent security, browser isolation, or agent governance
|
||||
**Template (top-level comment or reply):**
|
||||
|
||||
> This is the gap most "agent can use a browser" announcements skip.
|
||||
>
|
||||
> Molecule AI shipped a Chrome DevTools MCP integration that adds the governance layer underneath: https://docs.molecule.ai/blog/chrome-devtools-mcp
|
||||
>
|
||||
> The specific thing it adds: org API key attribution on every browser action, token-scoped sessions per agent (no cross-contamination between agents), and instant revocation. Makes browser automation in agents something you can show a security team, not just a developer.
|
||||
|
||||
---
|
||||
|
||||
## Priority targets (build this list before outreach)
|
||||
|
||||
These are real communities to monitor — not cold-email targets:
|
||||
|
||||
1. **r/programming** — browser automation + AI agents threads appear regularly
|
||||
2. **r/MachineLearning** — agent architecture discussions
|
||||
3. **LinkedIn AI agent practitioners** — follow posts by LangChain, CrewAI, AutoGen maintainers; engage substantively
|
||||
4. **MCP Discord / GitHub** — modelcontextprotocol/servers discussions
|
||||
5. **DEV.to** — AI + browser automation tags; search for "MCP" or "browser automation AI agent"
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Only post where there's genuine topical relevance
|
||||
- Add substantive context, not just a link
|
||||
- Lead with the problem, not the product
|
||||
- Do not post the same comment across multiple threads simultaneously
|
||||
- If a thread already has a good answer, don't add a redundant link
|
||||
- Marketing Lead reviews outreach messages before any are sent
|
||||
|
||||
## Tracking
|
||||
|
||||
| Target | Platform | Status |
|
||||
|--------|----------|--------|
|
||||
| MCP GitHub community | GitHub | Monitor |
|
||||
| r/programming | Reddit | Monitor |
|
||||
| LinkedIn practitioners | LinkedIn | Monitor |
|
||||
| DEV.to | DEV.to | Monitor |
|
||||
| Hacker News | Hacker News | Monitor |
|
||||
@ -1,134 +1,113 @@
|
||||
# Social Copy — Chrome DevTools MCP SEO Campaign
|
||||
## Blog Post: "Give Your AI Agent a Real Browser: MCP + Chrome DevTools"
|
||||
**URL:** /blog/browser-automation-ai-agents-mcp
|
||||
**Date:** 2026-04-20
|
||||
**Author:** Content Marketer (draft — for Social Media Brand review + publish)
|
||||
**Status:** DRAFT — pending Marketing Lead review
|
||||
# Chrome DevTools MCP — Social Copy
|
||||
Campaign: chrome-devtools-mcp-seo | Blog PR: docs#49
|
||||
Publish day: TBD (Day 1, separate from fly-deploy-anywhere)
|
||||
Status: Draft — pending Marketing Lead approval
|
||||
|
||||
---
|
||||
|
||||
## X / Twitter Thread
|
||||
## X (Twitter) — Primary thread (5 posts)
|
||||
|
||||
**Post 1 (Hook):**
|
||||
> AI agents are great at reasoning.
|
||||
They're terrible at clicking through a website.
|
||||
### Post 1 — Hook (P0 keyword: `AI agent browser control`)
|
||||
Your AI agent just made a purchase on your behalf.
|
||||
|
||||
The moment a task needs a real browser — forms, dynamic content, pages with no API — most agents hit a wall.
|
||||
What did it buy? From where? With which account?
|
||||
|
||||
We fixed that. 🧵
|
||||
Most agents operate in a black box. Browser DevTools MCP makes the browser a first-class
|
||||
tool — with org-level audit attribution on every action.
|
||||
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
**Post 2 (What we built):**
|
||||
> Molecule AI agents now control Chrome directly via MCP + Chrome DevTools Protocol.
|
||||
### Post 2 — Problem framing (P0 keyword: `MCP browser automation`)
|
||||
Browser automation for AI agents usually means: give the agent your credentials, hope it
|
||||
doesn't go somewhere unexpected, and check the logs after.
|
||||
|
||||
No Puppeteer wrappers.
|
||||
No per-session SaaS pricing.
|
||||
No human manually sequencing browser steps.
|
||||
That's not a governance model. That's a trust fall.
|
||||
|
||||
The agent decides when to navigate, extract, screenshot — just like a human would.
|
||||
Molecule AI's MCP governance layer for Chrome DevTools MCP gives you:
|
||||
→ Which agent accessed which session
|
||||
→ What it did (navigate, fill, screenshot, submit)
|
||||
→ Audit trail with org API key attribution
|
||||
|
||||
Code snippet:
|
||||
```python
|
||||
agent = Agent(
|
||||
mcp_tools=browser.tools(), # CDP over MCP
|
||||
)
|
||||
agent.run("Extract pricing from competitor.com")
|
||||
```
|
||||
One org API key prefix per integration. Instant revocation.
|
||||
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
**Post 3 (Why it matters):**
|
||||
> MCP gives AI models typed, structured tool calls — not buried prompts.
|
||||
### Post 3 — Use case, concrete (P0 keyword: `browser automation AI agents`)
|
||||
Real things teams use Chrome DevTools MCP for in production:
|
||||
|
||||
Browser automation via MCP means:
|
||||
→ Session persistence (cookies survive across calls)
|
||||
→ Streaming responses (no timeout on page loads)
|
||||
→ Agent decides the sequence, not a human wiring workflow nodes
|
||||
• Automated Lighthouse audits on every PR — agent runs the audit, reports the score, flags regressions
|
||||
• Visual regression detection — agent screenshots key pages, diffs against baseline, opens tickets on drift
|
||||
• Auth scraping — agent reads the authenticated state from an existing browser session
|
||||
|
||||
The governance layer means your security team can see all three in the audit trail.
|
||||
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
**Post 4 (Use cases):**
|
||||
> What can you actually do with a browser-wielding AI agent?
|
||||
### Post 4 — Competitive / positioning (P0 keyword: `MCP governance layer`)
|
||||
The MCP protocol lets you connect any compatible tool to any compatible agent.
|
||||
|
||||
• Competitive intelligence pipelines — agent visits sites, extracts data, writes summaries
|
||||
• Automated UI regression testing — describe expected state in plain language
|
||||
• AI-assisted data entry for legacy web UIs
|
||||
• Real-time price monitoring with Slack alerts
|
||||
What's been missing: visibility into what the agent actually *did* with that access.
|
||||
|
||||
All from the same MCP toolset.
|
||||
Molecule AI's MCP governance layer adds:
|
||||
• Per-action audit logging with org API key attribution
|
||||
• Token-scoped Chrome sessions — no credential sharing across agents
|
||||
• Instant revocation without redeployment
|
||||
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
**Post 5 (CTA):**
|
||||
> Molecule AI workspaces ship browser automation out of the box.
|
||||
### Post 5 — CTA
|
||||
Chrome DevTools MCP ships today with Molecule AI Phase 30.
|
||||
|
||||
Free, self-hostable. GitHub below.
|
||||
If you're running AI agents that interact with web UIs — there's a governance story
|
||||
you need to have ready before your security team asks.
|
||||
|
||||
→ [github.com/Molecule-AI/molecule-core](https://github.com/Molecule-AI/molecule-core)
|
||||
|
||||
*Full tutorial + code examples in the blog post.*
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
## LinkedIn Post
|
||||
## LinkedIn — Single post
|
||||
|
||||
**Single post:**
|
||||
**Title:** Why your AI agent's browser access needs a governance layer
|
||||
|
||||
AI agents can reason, plan, and call APIs — but put a dynamic website in front of them and they stall.
|
||||
**Body:**
|
||||
|
||||
The problem isn't the model. It's the tooling.
|
||||
Your AI agent can use a browser. That's useful. But "useful" isn't a security posture.
|
||||
|
||||
Most teams solve this one of two ways:
|
||||
→ Write custom Playwright wrappers and pray the prompt doesn't drift
|
||||
→ Pay per-session for a SaaS browser API
|
||||
When an agent operates inside a browser — filling forms, reading session state, navigating authenticated flows — most platforms give you two options: trust it completely, or don't let it near the browser at all.
|
||||
|
||||
Both are the wrong direction.
|
||||
Molecule AI's Chrome DevTools MCP integration adds a third option: visibility with control.
|
||||
|
||||
We built browser automation directly into Molecule AI workspaces via MCP + Chrome DevTools Protocol. The agent gets a live browser session with typed tool calls — it decides when to navigate, query, screenshot, and interact. No human wiring the sequence.
|
||||
Here's what "governance layer" actually means in this context:
|
||||
|
||||
Three lines of YAML config. No SaaS dependency. No Selenium fleet to manage.
|
||||
→ Every browser action is logged with the org API key prefix that made the call. You know which agent touched what session, every time.
|
||||
|
||||
Code example, four real-world use cases, and the full MCP → CDP bridge breakdown in the blog post.
|
||||
→ Chrome sessions are token-scoped. Agent A's session is not Agent B's session. No credential cross-contamination.
|
||||
|
||||
→ [Read: "Give Your AI Agent a Real Browser: MCP + Chrome DevTools"](https://github.com/Molecule-AI/molecule-core/blob/main/docs/blog/2026-04-20-chrome-devtools-mcp-seo/index.md)
|
||||
→ Revocation is instant. One API call, the key stops working, the session closes. No redeploy.
|
||||
|
||||
#AIagents #MCP #browserautomation #Python #LangChain
|
||||
→ Audit trails are exportable. Your security team can review them without a custom logging pipeline.
|
||||
|
||||
This is the difference between "the agent can use a browser" and "the agent's browser access is auditable, attributable, and revocable."
|
||||
|
||||
Chrome DevTools MCP is available now on all Molecule AI deployments.
|
||||
|
||||
→ [link: docs blog post]
|
||||
|
||||
---
|
||||
|
||||
## Image / Visual Recommendations
|
||||
## Campaign notes
|
||||
|
||||
| Platform | Asset | File |
|
||||
|---|---|---|
|
||||
| X/LinkedIn | Diagram: MCP bridge | `assets/mcp-bridge-diagram.svg` |
|
||||
| X (thread) | Comparison card | `assets/comparison-table-card.svg` |
|
||||
| X/LinkedIn | Code card | Create from blog post code snippet: `agent = Agent(mcp_tools=browser.tools())` |
|
||||
| X/LinkedIn | CTA graphic | "Your AI agent just got a browser." + GitHub link |
|
||||
|
||||
**Generated assets available in `docs/marketing/campaigns/chrome-devtools-mcp-seo/assets/`:**
|
||||
- `mcp-bridge-diagram.svg` — AI Agent → MCP → CDP → Chrome architecture diagram
|
||||
- `comparison-table-card.svg` — 3-approach comparison (Custom vs SaaS vs Molecule AI)
|
||||
|
||||
---
|
||||
|
||||
## Hashtag Set
|
||||
#AIagents #MCP #BrowserAutomation #Python #DeveloperTools #AIautomation #LangChain #CrewAI
|
||||
|
||||
---
|
||||
|
||||
## Campaign UTM Tags
|
||||
Append `?utm_source=twitter&utm_medium=social&utm_campaign=chrome-devtools-mcp-seo` to all links in social posts.
|
||||
|
||||
---
|
||||
|
||||
## Publishing Schedule
|
||||
| Platform | When | Notes |
|
||||
|---|---|---|
|
||||
| X thread | Blog publish day, 9am PT | 5 posts, one every 20–30 min |
|
||||
| LinkedIn | Blog publish day, 11am PT | Single post, same day as thread |
|
||||
| LinkedIn comment replies | +24h | Engage with early comments |
|
||||
|
||||
---
|
||||
|
||||
*Draft by Content Marketer 2026-04-20 — for Social Media Brand review before publishing*
|
||||
**Audience:** Developer / DevOps (X), Enterprise platform engineers (LinkedIn)
|
||||
**Tone:** Technical credibility, not hype. Lead with the governance gap, not the feature.
|
||||
**Differentiation:** Org API key audit attribution — this is the claim competitors can't match.
|
||||
**Use case pairings:** X → Lighthouse / visual regression (developer pain), LinkedIn → governance / compliance (enterprise buyer concern)
|
||||
**Hashtags:** #MCP #AIAgents #AgenticAI #MoleculeAI
|
||||
**Coordination:** Do NOT post on same day as fly-deploy-anywhere. Suggested spacing: Chrome DevTools MCP Day 1, Fly Day 3–5.
|
||||
|
||||
@ -0,0 +1,115 @@
|
||||
# Social Copy — Phase 30 Remote Workspaces / SaaS Federation
|
||||
|
||||
## Blog Post (Live)
|
||||
**URL:** `docs/blog/2026-04-20-remote-workspaces/index.md`
|
||||
**Title:** "One Canvas, Every Agent: Remote AI Agents and Fleet Visibility on Molecule AI"
|
||||
|
||||
---
|
||||
|
||||
## X / Twitter Thread
|
||||
|
||||
**Post 1 (Hook — fleet visibility problem):**
|
||||
> Your AI agents are scattered across 6 different clouds, 3 VPNs, and someone's laptop.
|
||||
Each one has its own token. Its own dashboard. Its own on-call rotation.
|
||||
|
||||
Molecule AI's Phase 30 ships one canvas that sees all of it.
|
||||
|
||||
---
|
||||
|
||||
**Post 2 (What it is):**
|
||||
> Remote agents are now first-class citizens on the Molecule AI canvas.
|
||||
|
||||
Register any agent — laptop, cloud VM, CI/CD runner, on-prem server — with a per-workspace bearer token. Send heartbeats every 30s. Done.
|
||||
|
||||
The canvas shows a purple REMOTE badge. That's how you know it's running on *your* infra, not ours.
|
||||
|
||||
---
|
||||
|
||||
**Post 3 (The security model):**
|
||||
> Here's what "remote agent" means for your security posture:
|
||||
|
||||
→ Bearer token issued once at registration, never again
|
||||
→ Secrets fetched on demand via API — never hardcoded or in env blocks
|
||||
→ Heartbeat TTL: 90s offline threshold, no silent failures
|
||||
→ X-Workspace-ID header for cross-network A2A — audit trail on every message
|
||||
|
||||
Built for production teams, not demos.
|
||||
|
||||
---
|
||||
|
||||
**Post 4 (Use cases):**
|
||||
> What actually runs on remote agents today:
|
||||
|
||||
→ CI/CD pipelines that open PRs, run tests, and post results back
|
||||
→ Laptops that run dev agents between standups
|
||||
→ On-prem servers that can't be containerized
|
||||
→ Cloud VMs in other regions — same canvas, different infra
|
||||
|
||||
All of them visible from one place.
|
||||
|
||||
---
|
||||
|
||||
**Post 5 (CTA + tutorial):**
|
||||
> New tutorial: "Register a Remote Agent on Molecule AI"
|
||||
|
||||
6 steps — external workspace, bearer token, heartbeat loop, A2A messaging.
|
||||
Copy-paste Python example included.
|
||||
|
||||
→ [Read the tutorial](https://github.com/Molecule-AI/molecule-core/blob/main/docs/tutorials/register-remote-agent.md)
|
||||
→ [Full launch post](https://github.com/Molecule-AI/molecule-core/blob/main/docs/blog/2026-04-20-remote-workspaces/index.md)
|
||||
|
||||
---
|
||||
|
||||
## LinkedIn Post
|
||||
|
||||
**Single post:**
|
||||
|
||||
We shipped Phase 30 — and the headline is fleet visibility.
|
||||
|
||||
If you're running AI agents across multiple environments (and most production teams are), you've probably built custom dashboards to track them, shared tokens that nobody wants to rotate, and lost sleep over whether that agent on the VPN is still alive.
|
||||
|
||||
Molecule AI's Remote Agents changes this. Register any agent — laptop, cloud VM, CI/CD runner, on-prem — with a per-workspace bearer token and a 30-second heartbeat. It appears on your canvas with a REMOTE badge. You manage it from there.
|
||||
|
||||
The security model is deliberate: tokens shown once, secrets pulled on demand, no long-lived credentials floating around. If an agent goes offline for 90 seconds, the canvas reflects it immediately.
|
||||
|
||||
If you've been managing a fleet of agents with a spreadsheet and Slack, this is the upgrade.
|
||||
|
||||
→ [Tutorial: Register a Remote Agent](https://github.com/Molecule-AI/molecule-core/blob/main/docs/tutorials/register-remote-agent.md)
|
||||
→ [Full launch post](https://github.com/Molecule-AI/molecule-core/blob/main/docs/blog/2026-04-20-remote-workspaces/index.md)
|
||||
|
||||
#AIagents #fleetmanagement #selfhosted #DevOps #AIAgents
|
||||
|
||||
---
|
||||
|
||||
## Image / Visual Recommendations
|
||||
|
||||
| Platform | Asset | Description |
|
||||
|---|---|---|
|
||||
| X (hook) | Fleet diagram | Canvas at center, 5 agent types radiating out (laptop, VM, CI, on-prem, SaaS). Purple REMOTE badge labels. |
|
||||
| X (security) | Token lifecycle card | 4 steps: Register → Token issued (once) → Secrets pulled on demand → Heartbeat every 30s. Monospace. Dark background. |
|
||||
| LinkedIn | Canvas screenshot mock | Canvas showing mixed fleet: 3 Docker workspaces, 2 REMOTE agents, all online. |
|
||||
| CTA | "One canvas, every agent." + GitHub link | |
|
||||
|
||||
---
|
||||
|
||||
## Publishing Schedule
|
||||
|
||||
| Platform | When | Notes |
|
||||
|---|---|---|
|
||||
| X thread | Day of publish, 9am PT | 5 posts, staggered 20-30 min |
|
||||
| LinkedIn | Day of publish, 11am PT | Same day as X |
|
||||
| Reddit r/LocalLLaMA | Day of publish, 12pm PT | Angle: fleet management for self-hosted agents |
|
||||
| Reddit r/MachineLearning | Day of publish, 1pm PT | Angle: multi-cloud agent orchestration |
|
||||
|
||||
---
|
||||
|
||||
## Keyword Targeting
|
||||
|
||||
Primary: `remote AI agent deployment` + `self-hosted AI agents platform`
|
||||
Secondary: `federated AI agents`, `AI agent fleet management`, `multi-cloud AI agent platform`
|
||||
|
||||
Thread posts should organically include "remote agent deployment" and "self-hosted" where natural.
|
||||
|
||||
---
|
||||
|
||||
*Draft by SEO Analyst 2026-04-21 — coordinating with Content Marketer on blog expansion (Action 3) and Social Media Brand on thread timing (#1182)*
|
||||
@ -1,6 +1,6 @@
|
||||
# Provisioning Workspaces on Fly Machines (CONTAINER_BACKEND=flyio)
|
||||
|
||||
Molecule AI can provision agent workspaces as [Fly Machines](https://fly.io/docs/machines/) instead of local Docker containers. Set `CONTAINER_BACKEND=flyio` on your platform and every `POST /workspaces` call creates a Fly Machine in your app — with tier-based resource limits, env-var injection, and A2A registration handled automatically.
|
||||
Molecule AI can provision agent workspaces on [Fly Machines](https://fly.io/docs/machines/) instead of local Docker containers. When `CONTAINER_BACKEND=flyio` is set, every `POST /workspaces` creates a Fly Machine and boots the workspace agent inside it — with tier-based resource limits, env-var injection, and A2A registration handled automatically. The platform manages the workspace (lifecycle, auth, routing); Fly manages the machine it runs on.
|
||||
|
||||
> **Scope note (PR #501):** Workspace images must already be published to GHCR before provisioning. The `delete` and `restart` platform endpoints are not yet fully wired to the Fly provisioner — use `flyctl machine stop/destroy` for teardown until a follow-up PR lands.
|
||||
|
||||
|
||||
269
docs/tutorials/register-remote-agent.md
Normal file
269
docs/tutorials/register-remote-agent.md
Normal file
@ -0,0 +1,269 @@
|
||||
# Register a Remote Agent on Molecule AI
|
||||
|
||||
Remote agents let you connect AI agents running on *any* infrastructure — your laptop, a cloud VM, a CI/CD pipeline, or an on-premise server — to a single Molecule AI canvas. Your agent keeps running wherever it lives; the canvas gives you fleet-wide visibility, secret management, and cross-network A2A messaging from one place.
|
||||
|
||||
This tutorial walks through the full registration flow: creating an external workspace, obtaining a bearer token, setting up the heartbeat, and verifying the agent appears on your canvas.
|
||||
|
||||
> **Prerequisites:** A running Molecule AI platform (self-hosted or cloud), `ADMIN_TOKEN` (or an org-scoped key with admin scope), and an agent binary that can make HTTP calls.
|
||||
|
||||
## How remote agents work
|
||||
|
||||
Molecule AI's remote agent system has three parts:
|
||||
|
||||
1. **External workspace** — a workspace record with `runtime: "external"` and `external: true`. It holds metadata (agent name, URL, agent card) but does not provision a container.
|
||||
2. **Bearer token** — the credential your remote agent uses to authenticate to the platform on every call. Issued once at registration; stored by the agent.
|
||||
3. **Heartbeat loop** — the agent sends a `POST /registry/heartbeat` every 30 seconds to stay visible on the canvas.
|
||||
|
||||
```
|
||||
Your infra (laptop / VM / CI) Molecule AI Platform
|
||||
│ │
|
||||
│ POST /workspaces (create external workspace)
|
||||
│────────────────────────────────────►│
|
||||
│ │
|
||||
│ POST /registry/register (get bearer token)
|
||||
│────────────────────────────────────►│
|
||||
│ ← auth_token
|
||||
│ │
|
||||
│ POST /registry/heartbeat (every 30s)
|
||||
│────────────────────────────────────►│ Canvas shows purple REMOTE badge
|
||||
│ │
|
||||
│ GET /secrets (fetch workspace secrets)
|
||||
│ POST /a2a (A2A messaging)
|
||||
│────────────────────────────────────►│
|
||||
```
|
||||
|
||||
## Step-by-step registration
|
||||
|
||||
### Step 1: Create an external workspace
|
||||
|
||||
```bash
|
||||
ADMIN_TOKEN="your-admin-token-or-org-key"
|
||||
PLATFORM_URL="https://platform.moleculesai.app"
|
||||
AGENT_URL="https://your-agent.example.com" # must be reachable from the platform
|
||||
|
||||
WORKSPACE=$(curl -s -X POST "${PLATFORM_URL}/workspaces" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "CI Agent",
|
||||
"runtime": "external",
|
||||
"external": true,
|
||||
"url": "https://your-agent.example.com"
|
||||
}')
|
||||
|
||||
WORKSPACE_ID=$(echo $WORKSPACE | jq -r '.id')
|
||||
echo "Workspace ID: ${WORKSPACE_ID}"
|
||||
```
|
||||
|
||||
The `runtime: "external"` flag tells the platform this workspace is agent-managed, not container-provisioned. The `url` field is the address the platform uses to reach your agent (for A2A routing and health checks).
|
||||
|
||||
Save the workspace ID — you'll use it in the next step.
|
||||
|
||||
### Step 2: Register the agent and receive a bearer token
|
||||
|
||||
```bash
|
||||
REG=$(curl -s -X POST "${PLATFORM_URL}/registry/register" \
|
||||
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"id\": \"${WORKSPACE_ID}\",
|
||||
\"url\": \"https://your-agent.example.com\",
|
||||
\"agent_card\": {
|
||||
\"name\": \"CI Agent\",
|
||||
\"runtime\": \"external\",
|
||||
\"version\": \"1.0\"
|
||||
}
|
||||
}")
|
||||
|
||||
AUTH_TOKEN=$(echo $REG | jq -r '.auth_token')
|
||||
echo "Auth token: ${AUTH_TOKEN}"
|
||||
|
||||
# IMPORTANT: the auth_token is shown once. Store it securely.
|
||||
# If lost, revoke and re-register.
|
||||
```
|
||||
|
||||
The response looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"auth_token": "rtok_01HZX... truncated ...",
|
||||
"workspace_id": "ws_01HZX...",
|
||||
"org_id": "org_01HZX...",
|
||||
"expires_at": null
|
||||
}
|
||||
```
|
||||
|
||||
Store `auth_token` in your agent's environment — **it's shown only once**. If you lose it, create a new external workspace and re-register.
|
||||
|
||||
### Step 3: Pull secrets on demand
|
||||
|
||||
Your agent fetches workspace secrets via the platform API using its bearer token. Secrets are never injected as environment variables for remote agents — the agent pulls them explicitly:
|
||||
|
||||
```bash
|
||||
curl -s "${PLATFORM_URL}/workspaces/${WORKSPACE_ID}/secrets" \
|
||||
-H "Authorization: Bearer ${AUTH_TOKEN}"
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"secrets": {
|
||||
"OPENAI_API_KEY": "sk-...",
|
||||
"GITHUB_TOKEN": "ghs_..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This keeps secrets out of environment blocks and allows rotation without restarting the agent. Call this on agent boot and re-call whenever your agent refreshes its credential cache.
|
||||
|
||||
### Step 4: Start the heartbeat loop
|
||||
|
||||
The heartbeat keeps your agent visible on the canvas. Send it every **30 seconds**:
|
||||
|
||||
```python
|
||||
import requests, time
|
||||
|
||||
AUTH_TOKEN = "rtok_01HZX..."
|
||||
WORKSPACE_ID = "ws_01HZX..."
|
||||
PLATFORM_URL = "https://platform.moleculesai.app"
|
||||
|
||||
while True:
|
||||
resp = requests.post(
|
||||
f"{PLATFORM_URL}/registry/heartbeat",
|
||||
headers={"Authorization": f"Bearer {AUTH_TOKEN}"},
|
||||
json={"workspace_id": WORKSPACE_ID},
|
||||
)
|
||||
if resp.status_code != 200:
|
||||
print(f"Heartbeat failed: {resp.status_code} {resp.text}")
|
||||
time.sleep(30)
|
||||
```
|
||||
|
||||
If the platform misses three consecutive heartbeats (90 seconds), it marks the agent as `offline` on the canvas. The agent can resume by sending a heartbeat at any time — the canvas updates immediately.
|
||||
|
||||
### Step 5: Send and receive A2A messages
|
||||
|
||||
Remote agents use the standard A2A protocol. Your agent polls for inbound tasks:
|
||||
|
||||
```bash
|
||||
curl -s -X POST "${PLATFORM_URL}/a2a" \
|
||||
-H "Authorization: Bearer ${AUTH_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Workspace-ID: ${WORKSPACE_ID}" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"message": {
|
||||
"role": "user",
|
||||
"parts": [{"kind": "text", "text": "Hello from a remote agent"}]
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
The `X-Workspace-ID` header identifies which workspace the message originates from. Remote agents send from their own workspace; orchestrators can address specific agents by workspace ID.
|
||||
|
||||
### Step 6: Verify the agent appears on the canvas
|
||||
|
||||
Open your Molecule AI canvas, navigate to **Workspaces**, and look for your agent. Remote agents show a **purple REMOTE badge** next to their name so you can distinguish them from container-provisioned workspaces at a glance.
|
||||
|
||||
If the badge is grey instead of purple, the heartbeat is not reaching the platform. Check:
|
||||
- The agent's outbound HTTPS can reach `platform.moleculesai.app`
|
||||
- The heartbeat loop is running and not crashing silently
|
||||
- The `auth_token` matches the workspace ID
|
||||
|
||||
## Agent code: minimal Python example
|
||||
|
||||
Here's a minimal agent that registers, starts the heartbeat, and can receive A2A tasks:
|
||||
|
||||
```python
|
||||
import requests, time, threading, json
|
||||
|
||||
PLATFORM_URL = "https://platform.moleculesai.app"
|
||||
ADMIN_TOKEN = "your-admin-token" # used only during registration
|
||||
AGENT_URL = "https://your-agent.example.com" # must be HTTPS and reachable
|
||||
|
||||
# Step 1: Create external workspace
|
||||
workspace = requests.post(
|
||||
f"{PLATFORM_URL}/workspaces",
|
||||
headers={"Authorization": f"Bearer {ADMIN_TOKEN}"},
|
||||
json={"name": "CI Agent", "runtime": "external", "external": True, "url": AGENT_URL},
|
||||
).json()
|
||||
WORKSPACE_ID = workspace["id"]
|
||||
|
||||
# Step 2: Register and get bearer token
|
||||
reg = requests.post(
|
||||
f"{PLATFORM_URL}/registry/register",
|
||||
headers={"Authorization": f"Bearer {ADMIN_TOKEN}"},
|
||||
json={
|
||||
"id": WORKSPACE_ID,
|
||||
"url": AGENT_URL,
|
||||
"agent_card": {"name": "CI Agent", "runtime": "external"},
|
||||
},
|
||||
).json()
|
||||
AUTH_TOKEN = reg["auth_token"]
|
||||
|
||||
# Step 3: Fetch secrets on boot
|
||||
secrets = requests.get(
|
||||
f"{PLATFORM_URL}/workspaces/{WORKSPACE_ID}/secrets",
|
||||
headers={"Authorization": f"Bearer {AUTH_TOKEN}"},
|
||||
).json()
|
||||
# Store secrets in your agent's credential store
|
||||
|
||||
# Step 4: Heartbeat loop (runs in background)
|
||||
def heartbeat_loop():
|
||||
while True:
|
||||
requests.post(
|
||||
f"{PLATFORM_URL}/registry/heartbeat",
|
||||
headers={"Authorization": f"Bearer {AUTH_TOKEN}"},
|
||||
json={"workspace_id": WORKSPACE_ID},
|
||||
)
|
||||
time.sleep(30)
|
||||
|
||||
threading.Thread(target=heartbeat_loop, daemon=True).start()
|
||||
|
||||
# Step 5: Poll for A2A tasks
|
||||
print(f"Registered. Workspace ID: {WORKSPACE_ID}")
|
||||
print("Heartbeat running in background.")
|
||||
```
|
||||
|
||||
## Self-hosted agents
|
||||
|
||||
For agents on private networks or air-gapped infrastructure, the platform must be able to reach `AGENT_URL` for A2A delivery. If your agent is behind a NAT or firewall:
|
||||
|
||||
- Use a tunnel (Cloudflare Tunnel, ngrok, frp) to expose the agent on a public HTTPS URL
|
||||
- Ensure the URL resolves and the agent's HTTP server handles `POST /a2a` requests
|
||||
- Check that your firewall allows outbound HTTPS to `PLATFORM_URL`
|
||||
|
||||
For air-gapped deployments without internet access, contact your Molecule AI sales team for on-premise deployment options.
|
||||
|
||||
## Revoking and re-registering
|
||||
|
||||
To rotate the agent's bearer token:
|
||||
|
||||
1. **Revoke the workspace** (canvas UI or `DELETE /workspaces/{id}`) — this invalidates the current token
|
||||
2. Re-run Step 1 and Step 2 above with a new workspace name
|
||||
3. Update your agent's `AUTH_TOKEN` with the new value
|
||||
|
||||
To revoke without deleting the workspace record, use `DELETE /workspaces/{id}/tokens` if your platform version supports it.
|
||||
|
||||
## Remote agents vs. Docker workspaces
|
||||
|
||||
| | Remote Agent | Docker Workspace |
|
||||
|---|---|---|
|
||||
| Infrastructure | Your own (laptop, VM, bare metal) | Platform-provisioned containers |
|
||||
| Token issuance | Manual via `/registry/register` | Automatic on container boot |
|
||||
| Secrets | Pulled on demand via API | Injected as env vars at startup |
|
||||
| Heartbeat | Your code sends it every 30s | Platform sends it from the container |
|
||||
| Canvas badge | Purple REMOTE | Standard (no badge) |
|
||||
| Tear-down | Revoke token + stop agent | `DELETE /workspaces/{id}` |
|
||||
| Best for | CI/CD agents, laptops, on-prem | Cloud VMs managed by the platform |
|
||||
|
||||
## What's next
|
||||
|
||||
- [Agent Card reference](../agent-runtime/agent-card.md) — publish your agent's capabilities so orchestrators can discover and route tasks
|
||||
- [A2A protocol reference](../api-protocol/a2a-protocol.md) — full message format, error codes, and streaming
|
||||
- [Registry and heartbeat reference](../api-protocol/registry-and-heartbeat.md) — heartbeat interval, offline detection, and error handling
|
||||
- [Remote workspaces blog post](../blog/2026-04-20-remote-workspaces/index.md) — the product announcement with fleet visibility context
|
||||
|
||||
> **Molecule AI is open source.** Remote agent support is in `molecule-core/registry/` on `main`.
|
||||
BIN
marketing/audio/audit-trail-observability.mp3
Normal file
BIN
marketing/audio/audit-trail-observability.mp3
Normal file
Binary file not shown.
BIN
marketing/audio/chrome-devtools-mcp-summary.mp3
Normal file
BIN
marketing/audio/chrome-devtools-mcp-summary.mp3
Normal file
Binary file not shown.
BIN
marketing/audio/phase30-video-vo.mp3
Normal file
BIN
marketing/audio/phase30-video-vo.mp3
Normal file
Binary file not shown.
@ -1,3 +1,29 @@
|
||||
## 2026-04-21T01:50Z
|
||||
- GH_TOKEN still invalid (~3 hours). All push/gh blocked. Read-only git works.
|
||||
- PR #1036 SUPERSEDED: team merged PR #1154 (fix/ssrf-url-validate-redactSecrets-admin-memories) which includes my exact MCP fixes. The same bugs were fixed by another agent while my branch was blocked.
|
||||
- Staging fast-forwarded to 742066c. Key merges: PR #1154 (SSRF + redactSecrets), PR #1168 (bootstrap-failed-and-console-proxy), PR #1184 (main promo), PR #1181 (staging promo).
|
||||
- SSRF test bug STILL EXISTS in staging (ssrf_test.go lines 62-63). My fix/ssrf-test-localhost branch has the fix (dac62fb). Will open PR when GH_TOKEN refreshes.
|
||||
- Key insight: when a team agent merges my same fixes while my PR is blocked, my branch becomes redundant. Verify staging doesn't already have the fix before preparing a new PR.
|
||||
|
||||
## 2026-04-21T02:50Z
|
||||
- GH_TOKEN RESTORED! Was invalid ~5 hours. Fixed by clearing x-access-token URL rewrites from git config, then using token directly in remote URL.
|
||||
- Pushed feat/memory-inspector-panel (force-push, cd8a1eb) — triggered CI on PR #1127. CI running but queued.
|
||||
- Pushed fix/ssrf-test-localhost (dac62fb) — opened PR #1192. CI running.
|
||||
- Closed PR #1036 (fix/mcp-type-assertions-ws-url-redaction) — was already superseded by PR #1154.
|
||||
- PR #1032 was ALREADY MERGED (confirmed via gh), not just "open". No action needed.
|
||||
- Reviewed PR #1194 (CI runner contention fix): moves changes detection to ubuntu-latest, adds concurrency cancel. Looks good.
|
||||
- CI queue is backed up — multiple parallel runs, self-hosted runner contention. My branches show 11+ min queue time.
|
||||
- Issue #1079 (unchecked ExecContext in scheduler panic defer): staging's PR #1166 merged fix, but ExecContext errors are still unchecked in both panic defers. Issue correctly flags this. Consider a follow-up if bandwidth allows.
|
||||
- Remote set to internal repo after fix. Internal pull clean (up to date).
|
||||
|
||||
## 2026-04-21T03:15Z
|
||||
- GH_TOKEN rotated AGAIN (ghs_72vTK7i6SRp6ujioy7Z0zThpuee7vO4JNHvU). Updated all git remotes (molecule-core, internal).
|
||||
- CI pipeline STALLED: 0 runs in_progress across the org. My runs queued 41+ min with no runner assignment. updated_at=null on Detect changes job.
|
||||
- Runners recovered at ~01:57 UTC (staging runs completing). My runs haven't cleared yet.
|
||||
- feat/memory-inspector-panel (run #24699254842): queued 41 min, Detect changes never started.
|
||||
- fix/ssrf-test-localhost (run #24698152165): queued 1h19m.
|
||||
- Reviewed PRs #1194, #1019, #1018, #1009. Issue #1079 (unchecked ExecContext) identified.
|
||||
- PRs #1036 closed, #1032 confirmed merged.
|
||||
|
||||
## 2026-04-21T03:40Z
|
||||
- GH_TOKEN rotated AGAIN (ghs_3rjPXOqVm3WNZ692xwQkVxE3sWLtsd2sd39D). 4th rotation in ~3h.
|
||||
@ -7,3 +33,34 @@
|
||||
- Queue analysis: ~300 runs across 3 pages. My runs at page 2 position ~100. Newer runs (02:20+) at page 1 top. Only 1-2 active runners.
|
||||
- Reviewed PRs #1222, #1221, #1217 — all look good.
|
||||
- PRs #1036 closed, #1032 confirmed merged. No further PR review opportunities.
|
||||
|
||||
## 2026-04-21T04:00Z
|
||||
- GH_TOKEN restored (ghs_EerpGUdxLFRqZqTEwoMtWZrdPZfXIP1wSrNa). 5th rotation.
|
||||
- PR #1127 ALREADY MERGED (head=9201179, confirmed via gh). feat/memory-inspector-panel branch done.
|
||||
- SSRF test fix (dac62fb, wantErr:true for localhost cases) exists only in molecule-core fix/ssrf-test-localhost branch (NOT in internal repo OR molecule-core staging/main). Created PR #1240 against staging.
|
||||
- Internal repo reset to origin/main (c5b8260) — another agent's tick overwrote mine (60f0e3e lost). The ssrf_test.go file does NOT exist in origin/main (695588b not in ancestry). Internal repo has no SSRF-related branches or PRs.
|
||||
- PR #1239 reviewed (org_id in Gin context for org-token callers): small, well-scoped. Can't approve (own PR).
|
||||
- CI queue: 73 queued, 0 in_progress. New runs (02:50+) being processed. My PR #1240 CI queued ~02:57.
|
||||
- Git remotes updated with new token for both repos.
|
||||
|
||||
## 2026-04-21T04:10Z
|
||||
- PR #1240 (SSRF test fix) — MERGED ✓. CI run #24701644710 success at 02:57Z.
|
||||
- Open PRs on molecule-core:
|
||||
- #1244 (fix/f1089-fireschedule-update-ctx): follow-up to #1241, dedicated context for post-fire UPDATE. CI queued ~03:04Z.
|
||||
- #1243 (fix/canvas-timer-state-orgs-page): eliminate flaky timer state. CI queued ~03:02Z.
|
||||
- #1242 (fix/ci-runner-queue-contention): removes ci.yml concurrency, adds codeql.yml concurrency. CI run failed (workflow file issue). Another agent's PR.
|
||||
- #1241 (fix/f1089-scheduler-ctx-fix-main): context.Background() in panic-recovery defer UPDATE. CI queued ~02:58Z.
|
||||
- CI queue: 52 queued, 0 in_progress. Runners active (3 SUCCESS runs since 02:56Z). My old queued runs still stuck, newer runs getting picked up within minutes.
|
||||
- GH_TOKEN: ghs_EerpGUdxLFRqZqTEwoMtWZrdPZfXIP1wSrNa. Still working.
|
||||
- Internal repo: up to date at 58769bb.
|
||||
- Issue #1062 (113 golangci-lint errcheck errors): PR #1229 merged (artifacts resp.Body.Close fix). Need to check remaining count.
|
||||
|
||||
## 2026-04-21T04:25Z
|
||||
- GH_TOKEN rotated (ghs_N7FohgCWrBpUQvR0qP4530cc4ZvpTJ17P8QF). 6th rotation. Remotes updated for both repos.
|
||||
- PR #1240 confirmed MERGED (SSRF test fix).
|
||||
- Open PRs: #1247 (sed regression fix — `$1` literal in 7 files, in flight), #1248 (CI yaml corruption fix — restores concurrency, OPEN). Both CI still running.
|
||||
- CI queue: 53 queued, 0 in_progress. 2 success runs since 03:00Z. Runners slow but active.
|
||||
- Feat/memory-inspector-panel branch (cd8a1eb) — PR merged, branch is stale. Could clean up but not critical.
|
||||
- Internal repo main forced-updated again (273674d instead of 58769bb). Another agent is writing over my ticks consistently.
|
||||
- No unassigned issues for my area. Issue #1245 (sed regression, CRITICAL) is being handled by PR #1247 (another agent's branch fix/sed-regression-1245).
|
||||
- Checked molecule-core staging (5831b4e) and main (273674d) — docs-focused updates.
|
||||
@ -127,9 +127,15 @@ func sweepStuckProvisioning(ctx context.Context, emitter ProvisionTimeoutEmitter
|
||||
continue
|
||||
}
|
||||
log.Printf("Provision-timeout sweep: %s stuck in provisioning > %s — marked failed", id, timeout)
|
||||
if emitErr := emitter.RecordAndBroadcast(ctx, "WORKSPACE_PROVISION_TIMEOUT", id, map[string]interface{}{
|
||||
"error": msg,
|
||||
"timeout_secs": timeoutSec,
|
||||
// Emit as WORKSPACE_PROVISION_FAILED, not _TIMEOUT, because the
|
||||
// canvas event handler only flips node state on the _FAILED case.
|
||||
// A separate event type was considered but the UI reaction is
|
||||
// identical either way — operators who need to distinguish can
|
||||
// tell from the `source` payload field.
|
||||
if emitErr := emitter.RecordAndBroadcast(ctx, "WORKSPACE_PROVISION_FAILED", id, map[string]interface{}{
|
||||
"error": msg,
|
||||
"timeout_secs": timeoutSec,
|
||||
"source": "provision_timeout_sweep",
|
||||
}); emitErr != nil {
|
||||
log.Printf("Provision-timeout sweep: broadcast failed for %s: %v", id, emitErr)
|
||||
}
|
||||
|
||||
@ -58,8 +58,8 @@ func TestSweepStuckProvisioning_FlipsOverdue(t *testing.T) {
|
||||
if emit.count() != 1 {
|
||||
t.Fatalf("expected 1 event, got %d", emit.count())
|
||||
}
|
||||
if emit.events[0].Type != "WORKSPACE_PROVISION_TIMEOUT" {
|
||||
t.Errorf("event type = %q, want WORKSPACE_PROVISION_TIMEOUT", emit.events[0].Type)
|
||||
if emit.events[0].Type != "WORKSPACE_PROVISION_FAILED" {
|
||||
t.Errorf("event type = %q, want WORKSPACE_PROVISION_FAILED", emit.events[0].Type)
|
||||
}
|
||||
if emit.events[0].WorkspaceID != "ws-stuck" {
|
||||
t.Errorf("workspace id = %q, want ws-stuck", emit.events[0].WorkspaceID)
|
||||
@ -72,7 +72,7 @@ func TestSweepStuckProvisioning_FlipsOverdue(t *testing.T) {
|
||||
// TestSweepStuckProvisioning_RaceSafe covers the case where UPDATE affects
|
||||
// 0 rows because the workspace flipped to online (or got restarted) between
|
||||
// the SELECT and the UPDATE. We should skip the event, not emit a false
|
||||
// WORKSPACE_PROVISION_TIMEOUT.
|
||||
// WORKSPACE_PROVISION_FAILED.
|
||||
func TestSweepStuckProvisioning_RaceSafe(t *testing.T) {
|
||||
mock := setupTestDB(t)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user