Files
ajarbot/n8n_current_workflow.json
Jordan Ramos 916f86725d feat: RSO observation system, child safety, Discord adapter, Telegram watchdog, email attachments
Core agent improvements:
- RSO (Relevance Scoring & Observation) system: interaction_logger, memory_scorer, signal_detector
- Memory access logging (memory_access_log table) for relevance scoring; high-signal turn detection
- Rich conversation storage for notable turns; compact_conversation truncates long user messages
- Task-type classifier (query/action/analysis/creative) for observation tagging
- Nested sub-agent visibility: deep delegations now register against the main agent's manager

Child safety (Gabriel profile):
- child_safety.py: filtering, audit logging, prompt constants for restricted sessions
- .kiro/specs/child-safety-profile: requirements, design, tasks specs
- GABRIEL_BOT_PROPOSAL.md: initial proposal doc
- Reduced context window (10 msgs) and tutor-mode identity for restricted users

Telegram adapter:
- Polling watchdog: auto-restarts updater if polling drops unexpectedly
- get_me() with exponential-backoff retry on NetworkError at startup
- Correct stop() ordering: signal watchdog before cancelling tasks

Email / Gmail:
- send_email: supports file attachments (attachments list param)
- get_email: surfaces attachment metadata in response

Scheduled tasks / weather:
- Remove OpenWeatherMap API calls from morning-weather task; use wttr.in exclusively
- New scheduled tasks and scheduler state persistence

Discord:
- adapters/discord/__init__.py scaffold
- discord-plugin: MCP plugin for Claude Code Discord integration (server.ts, skills, config)

Infrastructure:
- n8n workflow exports (garvis_webhook, content_pipeline variants)
- memory_workspace: context, homelab-repo-updates, weekly observation summaries, error logs
- UCS C240 migration plan doc
- requirements.txt: new deps
- .claude/settings.json, fix_hooks.py: hook/permission tuning
2026-04-23 07:54:01 -06:00

1 line
11 KiB
JSON

{"updatedAt":"2026-03-18T20:08:18.664Z","createdAt":"2026-03-18T05:17:33.507Z","id":"w6GZz40OLCDUfG2v","name":"Content Pipeline - BlendedFamilyKitchen","description":null,"active":false,"isArchived":false,"nodes":[{"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":30}]}},"id":"9ef020dc-bfa4-4fba-b19d-b3da3a0eeaca","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","typeVersion":1.2,"position":[224,304]},{"parameters":{"content":"## 1. NAS Drop Zone - Synology (192.168.2.200)\n\nCloe drops raw video files to a shared folder on the Synology NAS.\n\n**Folder Structure:**\n- /BlendedFamilyKitchen/raw/ = New uploads land here\n- /BlendedFamilyKitchen/processed/ = After AI processing\n- /BlendedFamilyKitchen/archive/ = After publishing\n\n**Access Method Options:**\n- Synology FileStation API (HTTP, port 5000/5001)\n- WebDAV (if enabled on NAS)\n- SMB mount from CT 113 (requires cifs-utils)\n\n**TODO - Infrastructure Setup:**\n1. Create shared folder BlendedFamilyKitchen on NAS\n2. Create sub-folders: raw/, processed/, archive/\n3. Create a dedicated NAS user for n8n API access\n4. Enable FileStation API or WebDAV on NAS\n5. Store credentials in n8n Credentials Manager\n6. Grant Cloe write access to raw/ only\n\n**FileStation API Endpoints:**\n- List files: /webapi/entry.cgi?api=SYNO.FileStation.List&method=list\n- Download: /webapi/entry.cgi?api=SYNO.FileStation.Download\n- Upload: /webapi/entry.cgi?api=SYNO.FileStation.Upload\n- Move/Rename: /webapi/entry.cgi?api=SYNO.FileStation.CopyMove","height":616,"width":560},"id":"722ec6f5-ec9d-4db9-be52-b6c492196c9b","name":"Sticky - NAS Drop Zone","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[-800,-544]},{"parameters":{"url":"http://192.168.2.200:5000/webapi/entry.cgi","sendQuery":true,"queryParameters":{"parameters":[{"name":"api","value":"SYNO.FileStation.List"},{"name":"version","value":"2"},{"name":"method","value":"list"},{"name":"folder_path","value":"/BlendedFamilyKitchen/raw"}]},"options":{}},"id":"a62c074e-2508-4b1e-a9af-371533d4ecab","name":"HTTP - Poll NAS for New Files","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[544,304]},{"parameters":{"conditions":{"options":{"caseSensitive":true,"leftValue":"","typeValidation":"strict"},"conditions":[{"id":"069dca64-6902-4201-8d23-e40cc23e0b31","leftValue":"={{ $json.data.files.length }}","rightValue":"0","operator":{"type":"number","operation":"gt"}}],"combinator":"and"},"options":{}},"id":"9f119a61-791a-4119-8300-ab3219e6b3bf","name":"IF - New Files Found?","type":"n8n-nodes-base.if","typeVersion":2.2,"position":[832,304]},{"parameters":{"assignments":{"assignments":[{"id":"fc7bce7d-a1d3-44ec-b494-58b75202b59e","name":"filename","value":"={{ $json.data.files[0].name }}","type":"string"},{"id":"6cf794c7-17e4-43c4-8e02-0d11fe914052","name":"filepath","value":"={{ $json.data.files[0].path }}","type":"string"},{"id":"4f1a241c-cf11-4d14-b4a3-9b3be0a8f860","name":"filesize_mb","value":"={{ Math.round($json.data.files[0].additional.size / 1048576) }}","type":"string"},{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"created","value":"={{ $json.data.files[0].additional.time.crtime }}","type":"string"}]},"options":{}},"id":"4b0d9125-0c09-424c-80c0-944848f6eb44","name":"Set - Extract File Metadata","type":"n8n-nodes-base.set","typeVersion":3.4,"position":[1104,208]},{"parameters":{"content":"## 2. AI Processing Stage\n\nOnce a new video is detected, it goes through AI processing.\n\n**Processing Steps (in order):**\n1. Download video from NAS to temp storage\n2. Run Whisper (or cloud STT) for caption/subtitle generation\n3. Generate thumbnail candidates from key frames\n4. Analyze content for tags and hashtags\n5. Calculate optimal TikTok posting time\n6. Save processed assets back to NAS /processed/\n\n**AI Service Options:**\n- Local Whisper on ubuntu-docker (107) or CML (108)\n- OpenAI Whisper API (cloud fallback)\n- Claude/GPT for hashtag and caption optimization\n- FFmpeg for thumbnail extraction\n\n**TODO - Infrastructure Setup:**\n1. Deploy Whisper container (or API endpoint)\n2. Set up FFmpeg on CT 113 or a worker VM\n3. Create AI processing API endpoint\n4. Configure temp storage for video processing\n5. Set up Claude API key in n8n for text generation\n\n**Expected Input:** Raw video file path on NAS\n**Expected Output:** Subtitled video, thumbnail, caption, hashtags, scheduled time","height":616,"width":560},"id":"9ec74678-0336-4e65-8244-ebe28336e648","name":"Sticky - AI Processing","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[1008,-544]},{"parameters":{"method":"POST","url":"http://localhost:8080/api/process-video","sendBody":true,"bodyParameters":{"parameters":[{"name":"video_path","value":"={{ $json.filepath }}"},{"name":"filename","value":"={{ $json.filename }}"},{"name":"tasks","value":"transcribe,thumbnail,hashtags,schedule"}]},"options":{"timeout":300000}},"id":"d8989829-11d8-428c-b1e4-5dc7e028a864","name":"HTTP - AI Processing","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[1408,208]},{"parameters":{"url":"http://192.168.2.200:5000/webapi/entry.cgi","sendQuery":true,"queryParameters":{"parameters":[{"name":"api","value":"SYNO.FileStation.CopyMove"},{"name":"version","value":"3"},{"name":"method","value":"start"},{"name":"path","value":"={{ $json.original_path }}"},{"name":"dest_folder_path","value":"/BlendedFamilyKitchen/processed"},{"name":"remove_src","value":"true"}]},"options":{}},"id":"2e566795-af32-443a-a0ce-5a71b4955eb9","name":"HTTP - Move to Processed","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[1712,208]},{"parameters":{"content":"## 3. Publishing Stage\n\nProcessed content gets scheduled for posting.\n\n**TikTok Publishing Options:**\n- TikTok Content Posting API (requires app approval)\n- Upload Post service (3rd party scheduling)\n- Manual: Notify Cloe with ready-to-post package\n\n**Publishing Flow:**\n1. Upload processed video to TikTok (or staging area)\n2. Attach AI-generated caption + hashtags\n3. Schedule post at optimal time\n4. Move original to /archive/ on NAS\n5. Send completion notification\n\n**TODO - Infrastructure Setup:**\n1. Register TikTok Developer App\n2. Get Content Posting API access (or choose alt service)\n3. Set up OAuth flow for Cloe's TikTok account\n4. Store TikTok credentials in n8n\n5. Configure Telegram bot for notifications\n6. Set up notification preferences (Cloe's chat ID)\n\n**Notification Should Include:**\n- Video title/filename\n- Generated caption (editable)\n- Suggested hashtags\n- Scheduled post time\n- Thumbnail preview\n- Approve / Edit / Cancel action buttons","height":700,"width":560},"id":"7f884982-7731-4bbb-959f-bd8d3dbc18f1","name":"Sticky - Publishing","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[1904,-544]},{"parameters":{"method":"POST","url":"https://open.tiktokapis.com/v2/post/publish/content/init/","sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer {{ $json.tiktok_token }}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"bodyParameters":{"parameters":[{"name":"title","value":"={{ $json.caption }}"},{"name":"privacy_level","value":"SELF_ONLY"}]},"options":{}},"id":"37be82e5-48c6-4d86-9c68-c5ed32f83f41","name":"HTTP - Schedule TikTok Post","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[2000,208]},{"parameters":{"url":"http://192.168.2.200:5000/webapi/entry.cgi","sendQuery":true,"queryParameters":{"parameters":[{"name":"api","value":"SYNO.FileStation.CopyMove"},{"name":"version","value":"3"},{"name":"method","value":"start"},{"name":"path","value":"={{ $json.filepath }}"},{"name":"dest_folder_path","value":"/BlendedFamilyKitchen/archive"},{"name":"remove_src","value":"true"}]},"options":{}},"id":"e1f2a3b4-c5d6-7890-abcd-111111111111","name":"HTTP - Archive Original","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[2304,208]},{"parameters":{"method":"POST","url":"https://api.telegram.org/bot<TOKEN>/sendMessage","sendBody":true,"bodyParameters":{"parameters":[{"name":"chat_id","value":"CLOE_CHAT_ID"},{"name":"text","value":"Content Pipeline Complete!\n\nFile: {{ $json.filename }}\nCaption: {{ $json.caption }}\nHashtags: {{ $json.hashtags }}\nScheduled: {{ $json.scheduled_time }}\n\nReview in TikTok drafts or reply to edit."},{"name":"parse_mode","value":"HTML"}]},"options":{}},"id":"92eeac8c-22e2-44db-adcd-c1d08e629e0b","name":"HTTP - Notify Cloe (Telegram)","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[2608,208]},{"parameters":{"content":"## 4. Error Handling and Notifications\n\n**On Failure at Any Stage:**\n- Log the error with timestamp + stage name\n- Notify Jordan via Telegram (Garvis bot)\n- Do NOT move the file - leave in raw/ for retry\n- Include error details in notification\n\n**Retry Logic:**\n- AI Processing: retry up to 2x with 60s delay\n- NAS operations: retry up to 3x with 30s delay\n- TikTok API: no auto-retry (rate limits)\n\n**TODO:**\n1. Add Error Trigger node to workflow\n2. Wire error handler to Telegram notification\n3. Configure retry settings on HTTP nodes\n4. Add logging to track pipeline performance","height":704,"width":520},"id":"f1e2d3c4-b5a6-7890-abcd-222222222222","name":"Sticky - Error Handling","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[2768,-544]}],"connections":{"Schedule Trigger":{"main":[[{"node":"HTTP - Poll NAS for New Files","type":"main","index":0}]]},"HTTP - Poll NAS for New Files":{"main":[[{"node":"IF - New Files Found?","type":"main","index":0}]]},"IF - New Files Found?":{"main":[[{"node":"Set - Extract File Metadata","type":"main","index":0}]]},"Set - Extract File Metadata":{"main":[[{"node":"HTTP - AI Processing","type":"main","index":0}]]},"HTTP - AI Processing":{"main":[[{"node":"HTTP - Move to Processed","type":"main","index":0}]]},"HTTP - Move to Processed":{"main":[[{"node":"HTTP - Schedule TikTok Post","type":"main","index":0}]]},"HTTP - Schedule TikTok Post":{"main":[[{"node":"HTTP - Archive Original","type":"main","index":0}]]},"HTTP - Archive Original":{"main":[[{"node":"HTTP - Notify Cloe (Telegram)","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","callerPolicy":"workflowsFromSameOwner","availableInMCP":false},"staticData":null,"meta":null,"pinData":{},"versionId":"e944235c-c708-4696-8517-085b42eaf35e","activeVersionId":null,"versionCounter":10,"triggerCount":0,"shared":[{"updatedAt":"2026-03-18T05:17:33.507Z","createdAt":"2026-03-18T05:17:33.507Z","role":"workflow:owner","workflowId":"w6GZz40OLCDUfG2v","projectId":"bPDtIdpuaSG2yKHe","project":{"updatedAt":"2026-03-18T04:50:54.011Z","createdAt":"2025-12-02T03:54:36.800Z","id":"bPDtIdpuaSG2yKHe","name":"Jordan Ramos <jramosdirect2@gmail.com>","type":"personal","icon":null,"description":null,"creatorId":"3e4c7deb-4c2f-43fe-b745-50eb81fb5275"}}],"tags":[],"activeVersion":null}