Artifacts Publishing Pattern
Purpose
Section titled “Purpose”Publish static HTML content accessible via public URL. Generate reports, dashboards, and shareable documents that users can view in a browser.
When to Use
Section titled “When to Use”| Use Case | Example |
|---|---|
| Reports | Purchase analysis, research results, comparison tables |
| Dashboards | Status pages, metrics visualization |
| Shareable content | Documents, presentations, portfolios |
| Notifications | Generate report + send URL via Telegram |
| User deliverables | Anything user needs to view in browser |
Structure
Section titled “Structure”[generate-data] → [create-html] → [upload-artifact] → [share-url]Implementation
Section titled “Implementation”Direct Upload Pattern
Section titled “Direct Upload Pattern”When agent generates HTML in memory:
{ "id": "generate-and-upload", "type": "agent-directive", "directive": "Generate HTML report from analysis data.\n\n**Data:**\n{{note:analysis-results}}\n\nCreate responsive HTML with Tailwind CDN.\n\nUpload using:\nartifacts({ action: \"upload\", name: \"report.html\", content: \"<html>...\" })\n\nSave the returned `url` as report_url.", "completionCondition": "Report uploaded and URL obtained", "inputSchema": { "type": "object", "required": ["report_url", "uploaded"], "properties": { "report_url": { "type": "string" }, "uploaded": { "type": "boolean" } } }, "connections": { "success": "notify-user" }}Token-based Upload Pattern
Section titled “Token-based Upload Pattern”When agent creates files locally first:
{ "id": "upload-via-token", "type": "agent-directive", "directive": "Upload the report file.\n\n1. Get token: artifacts({ action: \"token\", ttlMinutes: 30 })\n2. Read file from {{report_file_path}}\n3. POST to the uploadUrl with content\n4. Save response url", "inputSchema": { "properties": { "report_url": { "type": "string" }, "uploaded": { "type": "boolean" } } }}Conditional Based on Capabilities
Section titled “Conditional Based on Capabilities”Route based on agent’s file access:
{ "id": "check-file-access", "type": "condition", "condition": { "operator": "eq", "left": { "contextPath": "can_create_files" }, "right": true }, "connections": { "true": "generate-file-then-upload", "false": "generate-and-upload-direct" }}MCP Tool Usage
Section titled “MCP Tool Usage”Upload Artifact
Section titled “Upload Artifact”artifacts({ action: "upload", name: "purchase-report.html", content: `<!DOCTYPE html><html><head> <script src="https://cdn.tailwindcss.com"></script></head><body class="bg-gray-50 p-8"> <h1 class="text-2xl font-bold">Report</h1></body></html>`, executionId: "exec-123" // Optional: link to workflow})Response:
{ "success": true, "data": { "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "url": "https://moiraqq.com/a/a1b2c3d4...", "name": "purchase-report.html", "size": 1234, "expiresAt": "2025-02-28T10:00:00.000Z" }}Update Artifact
Section titled “Update Artifact”artifacts({ action: "update", uuid: "a1b2c3d4...", content: "<html>...updated...</html>", name: "report-v2.html" // Optional})Check Quota
Section titled “Check Quota”artifacts({ action: "stats"})// Returns: totalArtifacts, totalSize, storageLimit, usedPercentList Artifacts
Section titled “List Artifacts”artifacts({ action: "list", limit: 20})Quotas and Limits
Section titled “Quotas and Limits”| Limit | Value |
|---|---|
| Storage per user | 100 MB |
| File count | 50 artifacts |
| Max file size | 5 MB |
| Token TTL | 1-1440 minutes |
| Expiration | 30 days |
HTML Generation Tips
Section titled “HTML Generation Tips”Use Tailwind CDN
Section titled “Use Tailwind CDN”<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.tailwindcss.com"></script></head><body class="bg-gray-50 min-h-screen"> <!-- Content --></body></html>Responsive Layout
Section titled “Responsive Layout”<div class="container mx-auto px-4 py-8"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <!-- Cards --> </div></div>Product Card
Section titled “Product Card”<div class="bg-white rounded-lg shadow-md p-6"> <h3 class="text-lg font-semibold">Product Name</h3> <p class="text-gray-600 mt-2">Description</p> <div class="mt-4 flex justify-between items-center"> <span class="text-2xl font-bold text-green-600">$999</span> <a href="https://store.com/product" class="bg-blue-500 text-white px-4 py-2 rounded" target="_blank" rel="noopener noreferrer"> Buy Now </a> </div></div>Comparison Table
Section titled “Comparison Table”<table class="w-full border-collapse"> <thead> <tr class="bg-gray-100"> <th class="border p-3 text-left">Product</th> <th class="border p-3 text-left">Price</th> <th class="border p-3 text-left">Rating</th> </tr> </thead> <tbody> <tr class="hover:bg-gray-50"> <td class="border p-3">Product A</td> <td class="border p-3">$599</td> <td class="border p-3">4.5/5</td> </tr> </tbody></table>Integration with Notifications
Section titled “Integration with Notifications”Combine with telegram notifications:
{ "id": "notify-with-link", "type": "agent-directive", "directive": "Send the report URL to user via Telegram.\n\nURL: {{report_url}}\n\nUse telegram-notification to share the link.", "connections": { "success": "end" }}Real Example
Section titled “Real Example”From a purchase analysis workflow:
{ "id": "create-report", "type": "agent-directive", "directive": "Create HTML report with product recommendations.\n\n**Analysis data:**\n{{note:purchase-{{executionId}}-03-analysis}}\n\nGenerate responsive HTML:\n- Product cards with images, prices, links\n- Comparison table\n- Recommendation summary\n\nUpload: artifacts({ action: \"upload\", name: \"purchase-{{executionId}}.html\", content: html, executionId: \"{{executionId}}\" })", "inputSchema": { "properties": { "report_url": { "type": "string" }, "uploaded": { "type": "boolean" } }, "required": ["report_url"] }}Best Practices
Section titled “Best Practices”Descriptive Names
Section titled “Descriptive Names”// Goodartifacts({ name: "purchase-analysis-2025-01-31.html" })
// Badartifacts({ name: "report.html" })Link to Execution
Section titled “Link to Execution”artifacts({ action: "upload", name: "report.html", content: htmlContent, executionId: context.executionId})Benefits:
- Track which execution created which artifact
- Query artifacts by execution
- Clean up when execution archived
Handle Errors
Section titled “Handle Errors”{ "id": "upload-report", "type": "agent-directive", "directive": "Upload report. Check quota first. If upload fails, inform user.", "connections": { "success": "notify-user", "error": "handle-upload-error" }}Anti-patterns
Section titled “Anti-patterns”Using Artifacts for Data Storage
Section titled “Using Artifacts for Data Storage”Use notes for JSON data, artifacts for presentable HTML only.
Not Checking Quotas
Section titled “Not Checking Quotas”Always check stats before large uploads. Handle quota exceeded errors.
Non-responsive HTML
Section titled “Non-responsive HTML”Use Tailwind or media queries. Fixed-width layouts break on mobile.
Related Patterns
Section titled “Related Patterns”- Notes Persistence - For structured data storage
- Workspace - For file organization