Skip to content

Route AgentTask creation through emit - #1114

Open
johnpooch wants to merge 2 commits into
mainfrom
claude/agent-task-queue-jyhen2
Open

Route AgentTask creation through emit#1114
johnpooch wants to merge 2 commits into
mainfrom
claude/agent-task-queue-jyhen2

Conversation

@johnpooch

Copy link
Copy Markdown
Owner

What this PR does

Step 3 of the AgentTask direction (steps 1–2: #1110, #1113). Makes agent a third emit consumer alongside notification and channel event, so bot work is triggered by domain events instead of Django signals — the consistency goal from the original discussion.

How it works

  • New agent/registry.py holds AgentTaskSpec classes registered per event, mirroring notification.registry / channel.registry:
    • @register("phase_started")PhaseStartedSpec → plan tasks for bot members
    • @register("phase_state_confirmed")PhaseStateConfirmedSpec → finalize tasks (runs the "all humans confirmed, bots still pending" check — Option A: the event is dumb, the spec holds the bot-aware logic, keeping bot knowledge inside agent)
    • @register("channel_message")ChannelMessageSpec → reply tasks (skips bot senders)
  • AgentTask.objects.create_from_event(event_type, context) now takes the emit (event_type, context) signature, looks up the spec, and enqueues whatever tasks it returns via _enqueue (unchanged get-or-create + defer).
  • emit/dispatch.py gains the AgentTask consumer; emit/context.py carries the message object so the reply spec can key its task on it.

Emit sites

  • phase_started — emitted where a phase becomes active: game start (game/models.py), resolution (phase/models.py, guarded so a game-ending phase no longer spawns plan tasks), and revert.
  • phase_state_confirmed — emitted when orders are confirmed (phase/serializers.py).
  • reply reuses the existing emit("channel_message", …) — no new site.

Removed

  • agent/signals.py and agent/decorators.py are deleted; their trigger logic moved into the specs. This drops the pre_save phase-status capture, which slightly lowers the query count on the game-start and phase-creation paths (perf assertions in game/tests.py and phase/tests.py updated: −1 each).

Behavior notes

  • reply now triggers on the emitted channel_message (the real posted-message event) rather than any raw ChannelMessage ORM create — more correct, and bot-sent messages still don't trigger replies.
  • Verified across agent, emit, game, phase, channel, integration, and notification suites.

Checklist

  • This PR does one thing — no unrelated fixes, refactors, or drive-by cleanups bundled in
  • For PRs of any significant complexity: self-reviewed the diff against main (the /review-pr skill's gh dependency isn't wired in this environment, so the review was run manually) — no correctness issues found
  • Tests cover the change — specs exercised end-to-end via the domain paths, plus a direct spec test for the finalize "humans still pending" branch
  • Screenshots embedded in the PR description for any visual changes (see CLAUDE.md) — n/a, backend-only, no visual changes

🤖 Generated with Claude Code


Generated by Claude Code

Make agent a third emit consumer alongside notification and channel event,
so bot work is triggered by domain events instead of Django signals:

- New agent/registry.py holds AgentTaskSpec classes registered per event —
  PhaseStartedSpec (plan), PhaseStateConfirmedSpec (finalize), and
  ChannelMessageSpec (reply) — mirroring notification.registry and
  channel.registry. AgentTask.objects.create_from_event(event_type, context)
  looks up the spec and enqueues the tasks it returns.
- emit/dispatch.py gains the AgentTask consumer; emit/context.py carries the
  message object so the reply spec can key on it.
- New phase_started and phase_state_confirmed events are emitted where a phase
  becomes active (game start, resolution, revert) and where orders are
  confirmed. reply reuses the existing channel_message event. phase_started at
  resolution only fires when the new phase stays active, so a game-ending phase
  no longer spawns plan tasks.
- agent/signals.py and agent/decorators.py are deleted; their trigger logic
  moves into the specs. This drops the pre_save phase-status capture, which
  slightly lowers the query count on the game-start and phase-creation paths
  (perf assertions updated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJpwkPRdgx4u6H2bMchrUk
@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for diplicity-variant-creator canceled.

Name Link
🔨 Latest commit 4554533
🔍 Latest deploy log https://app.netlify.com/projects/diplicity-variant-creator/deploys/6a69d3a0f616cb0008ac0dc3

@github-actions

Copy link
Copy Markdown
Contributor

Warning

WIP limit exceeded. There are now 11 open pull requests — the project target is 5 or fewer.

Please close or merge an existing PR before continuing with this one.

…ue-jyhen2

# Conflicts:
#	service/agent/decorators.py
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.

2 participants