Skip to content

feat: thread reply edit vs generate logic (REC-68)#439

Open
recoup-coding-agent wants to merge 1 commit intotestfrom
feature/rec-68-thread-reply-edit-logic
Open

feat: thread reply edit vs generate logic (REC-68)#439
recoup-coding-agent wants to merge 1 commit intotestfrom
feature/rec-68-thread-reply-edit-logic

Conversation

@recoup-coding-agent
Copy link
Copy Markdown
Collaborator

@recoup-coding-agent recoup-coding-agent commented Apr 14, 2026

Summary

  • When a user tags the Recoup Content Agent in a thread of existing content, the bot now determines whether to edit existing content or generate new content
  • Uses AI classification to detect intent from the user's message
  • Edit flow: parses natural-language instructions into ffmpeg operations (trim, crop, resize, overlay_text) and triggers the edit task with the previously generated video URL
  • Generate flow: re-runs the full content creation pipeline with new parameters
  • Thread state now persists video URLs on completion for subsequent edits

Changes

  • lib/agents/content/types.ts — Add videoUrls and imageUrls to ContentAgentThreadState
  • lib/agents/content/handleContentAgentCallback.ts — Store video URLs in thread state on completion
  • lib/agents/content/createContentIntentAgent.ts — New AI agent for edit vs generate classification
  • lib/agents/content/parseContentIntent.ts — Wrapper for intent classification
  • lib/agents/content/createEditOperationsAgent.ts — New AI agent for parsing NL edit instructions into ffmpeg ops
  • lib/agents/content/parseEditOperations.ts — Wrapper for edit operations parsing
  • lib/trigger/triggerEditContent.ts — New trigger function for ffmpeg-edit task
  • lib/agents/content/handlers/registerOnSubscribedMessage.ts — Full rewrite with edit/generate/running/failed state handling

Related

Test plan

  • Tag bot in a completed content thread with "make it 10 seconds" → should trigger edit flow
  • Tag bot in a completed content thread with "generate 3 more videos" → should trigger generate flow
  • Tag bot in a running thread → should still respond "Still generating..."
  • Tag bot in a failed/timeout thread → should suggest starting a new thread
  • Verify edit results are polled and posted back to thread

🤖 Generated with Claude Code


Summary by cubic

Implements REC-68 by letting the Content Agent classify thread replies as “edit” or “generate” and run the right flow. Adds NL-to-ffmpeg edit parsing and persists video URLs for smooth follow-up edits.

  • New Features
    • Classifies intent from replies as edit or generate to meet REC-68.
    • Edit flow: parses instructions (trim, crop, resize, overlay_text), triggers ffmpeg-edit via @trigger.dev/sdk, and polls results.
    • Generate flow: re-runs content creation with parsed params and supports attached audio/images.
    • Persists videoUrls/imageUrls in thread state on completion for chained edits.
    • Better thread UX: responds during running, and guides users on failed/timeout threads.

Written for commit 3506958. Summary will update on new commits.

When a user tags the Recoup Content Agent in the thread of existing
content, the bot now:
- Classifies user intent as "edit" or "generate" using an AI agent
- For edits: parses natural-language edit instructions into ffmpeg
  operations (trim, crop, resize, overlay_text) and triggers the
  ffmpeg-edit task with the previously generated video URL
- For new generation: re-runs the full content creation pipeline
  with new parameters parsed from the reply

Key changes:
- ContentAgentThreadState stores videoUrls on completion
- handleContentAgentCallback persists video URLs in thread state
- New AI agents: createContentIntentAgent (edit vs generate),
  createEditOperationsAgent (NL to ffmpeg ops)
- registerOnSubscribedMessage handles completed/failed/timeout states
- triggerEditContent wraps ffmpeg-edit task triggering

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
recoup-api Ready Ready Preview Apr 14, 2026 9:49pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@recoup-coding-agent has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes and 42 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 59 minutes and 42 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ed0dd9d-2c9e-4299-8640-0281b089f38e

📥 Commits

Reviewing files that changed from the base of the PR and between b9341e3 and 3506958.

📒 Files selected for processing (8)
  • lib/agents/content/createContentIntentAgent.ts
  • lib/agents/content/createEditOperationsAgent.ts
  • lib/agents/content/handleContentAgentCallback.ts
  • lib/agents/content/handlers/registerOnSubscribedMessage.ts
  • lib/agents/content/parseContentIntent.ts
  • lib/agents/content/parseEditOperations.ts
  • lib/agents/content/types.ts
  • lib/trigger/triggerEditContent.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/rec-68-thread-reply-edit-logic

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 8 files

Confidence score: 3/5

  • There is a concrete regression risk in lib/agents/content/createEditOperationsAgent.ts: crop operations may pass validation without crop parameters, which can send invalid payloads to the ffmpeg edit task and fail at runtime.
  • lib/agents/content/handlers/registerOnSubscribedMessage.ts is flagged for maintainability (over 100 lines, mixed responsibilities), which increases future change risk even if it may not immediately break behavior.
  • Given a medium-severity runtime validation gap plus structural complexity concerns, this is mergeable with caution but carries some user-impacting risk if unaddressed.
  • Pay close attention to lib/agents/content/createEditOperationsAgent.ts and lib/agents/content/handlers/registerOnSubscribedMessage.ts - crop validation correctness and module split/readability are the key risk areas.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/agents/content/handlers/registerOnSubscribedMessage.ts">

<violation number="1" location="lib/agents/content/handlers/registerOnSubscribedMessage.ts:2">
P1: Custom agent: **Enforce Clear Code Style and Maintainability Practices**

This file now exceeds the 100-line limit and bundles multiple responsibilities in one module. Split the edit/generate helpers into smaller files to keep this file under 100 lines as required by the maintainability rule.</violation>
</file>

<file name="lib/agents/content/createEditOperationsAgent.ts">

<violation number="1" location="lib/agents/content/createEditOperationsAgent.ts:13">
P2: `crop` operations can validate without any crop parameters, allowing invalid edit payloads to be sent to the ffmpeg edit task.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant User as User (Slack/Client)
    participant Bot as Content Agent
    participant State as Thread State Store
    participant AI as AI Agents (Intent/Edit)
    participant Tasks as Trigger.dev (Tasks)
    participant Callback as handleContentAgentCallback

    User->>Bot: Replies to existing thread
    Bot->>State: Fetch thread state
    State-->>Bot: { status, videoUrls, artistAccountId, ... }

    alt status == "running"
        Bot-->>User: "Still generating..."
    else status == "failed" / "timeout"
        Bot-->>User: "Please start a new thread"
    else status == "completed"
        Note over Bot,AI: NEW: Decision Logic (REC-68)
        Bot->>AI: NEW: parseContentIntent(message, context)
        AI-->>Bot: { action: "edit" | "generate" }

        alt action == "edit"
            Bot->>AI: NEW: parseEditOperations(message)
            AI-->>Bot: { operations, template }
            
            Note over Bot,Tasks: NEW: Edit Execution Flow
            Bot->>Tasks: NEW: triggerEditContent(videoUrl, operations)
            Tasks-->>Bot: runId
        else action == "generate"
            Note over Bot,Tasks: Re-run Generation Flow
            Bot->>Tasks: triggerCreateContent(newParams)
            Tasks-->>Bot: runIds
        end

        Bot->>State: updateState({ status: "running", runIds })
        Bot->>Tasks: triggerPollContentRun(runIds, threadId)
        Bot-->>User: Post Task Card ("Started")
    end

    Note over Tasks,Callback: Background Processing
    Tasks->>Callback: Task Success (Webhook)
    Callback->>State: CHANGED: Persist videoUrls in state
    Callback->>State: updateState({ status: "completed" })
    Callback-->>User: Post final media results
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

@@ -1,8 +1,42 @@
import type { ContentAgentBot } from "../bot";
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Custom agent: Enforce Clear Code Style and Maintainability Practices

This file now exceeds the 100-line limit and bundles multiple responsibilities in one module. Split the edit/generate helpers into smaller files to keep this file under 100 lines as required by the maintainability rule.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/agents/content/handlers/registerOnSubscribedMessage.ts, line 2:

<comment>This file now exceeds the 100-line limit and bundles multiple responsibilities in one module. Split the edit/generate helpers into smaller files to keep this file under 100 lines as required by the maintainability rule.</comment>

<file context>
@@ -1,8 +1,42 @@
 import type { ContentAgentBot } from "../bot";
+import type { ContentAgentThreadState } from "../types";
+import { parseContentIntent } from "../parseContentIntent";
+import { parseEditOperations } from "../parseEditOperations";
</file context>
Fix with Cubic

duration: z.number().positive().describe("Duration in seconds."),
}),
z.object({
type: z.literal("crop"),
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: crop operations can validate without any crop parameters, allowing invalid edit payloads to be sent to the ffmpeg edit task.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/agents/content/createEditOperationsAgent.ts, line 13:

<comment>`crop` operations can validate without any crop parameters, allowing invalid edit payloads to be sent to the ffmpeg edit task.</comment>

<file context>
@@ -0,0 +1,87 @@
+    duration: z.number().positive().describe("Duration in seconds."),
+  }),
+  z.object({
+    type: z.literal("crop"),
+    aspect: z.string().optional().describe('Aspect ratio like "9:16", "1:1", "16:9".'),
+    width: z.number().int().positive().optional(),
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant