Skip to content

feat(system-task): DispatchMessageTask wrapping agents/dispatch-message#2051

Merged
chubes4 merged 2 commits into
mainfrom
feat/dispatch-message-task
May 16, 2026
Merged

feat(system-task): DispatchMessageTask wrapping agents/dispatch-message#2051
chubes4 merged 2 commits into
mainfrom
feat/dispatch-message-task

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented May 16, 2026

Summary

Adds DispatchMessageTask — a thin system_task wrapper around the canonical agents/dispatch-message ability (agents-api v0.107.0+). This is the DM-side bridge that lets a scheduled flow tick hand an outbound message off to whichever channel runtime is registered via the wp_agent_dispatch_message_handler filter, without DM needing any knowledge of the underlying transport (CLI runtime in DMC, future Slack/WhatsApp/etc. runtimes, …).

The shape mirrors AgentCallTask exactly: resolve the ability, forward params, surface canonical output or WP_Error into the job result envelope.

Closes #2049

Files

  • inc/Engine/AI/System/Tasks/DispatchMessageTask.php (new) — new SystemTask subclass. getTaskType() returns dispatch_message. executeTask() resolves wp_get_ability( 'agents/dispatch-message' ), forwards the canonical input (channel, recipient, message, plus optional conversation_id / attachments / client_context / metadata), and routes the result into completeJob() or failJob() per the SystemTask base contract. Handles both wrapped ({ task, params: { … } }) and flat ({ channel, recipient, message }) handler_config shapes, stripping SystemTask scaffolding before forwarding to the ability.
  • inc/Engine/AI/System/SystemAgentServiceProvider.php — registers \$tasks['dispatch_message'] = DispatchMessageTask::class; adjacent to the existing agent_call sibling.
  • tests/dispatch-message-task-smoke.php (new) — pure-PHP smoke covering source-level registration, ability-missing failure, handler success envelope, WP_Error propagation, and flat-shape passthrough.

Acceptance criteria (from #2049)

  • task: dispatch_message is a recognized system_task type (registered in SystemAgentServiceProvider::getBuiltInTasks()).
  • Pipeline runs with this task type call agents/dispatch-message once per execution (executeTask resolves the ability and calls \$ability->execute( \$input ) exactly once per invocation).
  • Task fails gracefully (clear log message, job marked failed, no fatal) when agents-api or the ability is missing — error message explicitly names the ability slug and the agents-api substrate.
  • No knowledge of any specific transport in the task code — the task source contains zero references to kimaki / discord / slack / telegram / whatsapp / cc-connect. Channel resolution stays inside the ability + its registered handler.
  • Smoke test covers all four paths (registered, ability-missing, handler success, handler WP_Error) plus a bonus flat-shape passthrough check.
  • Conventional commit messages (feat(system-task): … and test(system-task): …). No CHANGELOG edits. No version bumps.

Smoke test output

```
$ php tests/dispatch-message-task-smoke.php
dispatch-message task smoke (#2049)

[1] task file + provider registration:
✓ DispatchMessageTask.php exists
✓ class extends SystemTask
✓ getTaskType returns dispatch_message
✓ task references the canonical ability slug
✓ provider imports DispatchMessageTask
✓ provider maps dispatch_message task id
✓ provider maps to DispatchMessageTask::class

[2] no transport-specific names in the new code:
✓ task source contains no 'kimaki'
✓ task source contains no 'discord'
✓ task source contains no 'slack'
✓ task source contains no 'telegram'
✓ task source contains no 'whatsapp'
✓ task source contains no 'cc-connect'

[3] ability-missing path fails the job cleanly:
✓ ability missing: no job completed
✓ ability missing: job failed once
✓ ability missing: failed job id propagated
✓ ability missing: error mentions ability slug
✓ ability missing: error mentions agents-api substrate

[4] handler success path completes the job with canonical output:
✓ success: job completed once
✓ success: no job failures
✓ success: completed job id propagated
✓ success: sent flag in envelope
✓ success: channel in envelope
✓ success: recipient in envelope
✓ success: message_id in envelope
✓ success: metadata in envelope
✓ success: completed_at timestamp present
✓ success: channel forwarded
✓ success: recipient forwarded
✓ success: message forwarded
✓ success: conversation_id forwarded as null
✓ success: attachments forwarded
✓ success: client_context forwarded
✓ success: metadata forwarded
✓ success: SystemTask wrapper key task is stripped

[5] handler WP_Error path fails the job with the error message:
✓ wp_error: no job completed
✓ wp_error: job failed once
✓ wp_error: failed job id propagated
✓ wp_error: error code surfaced
✓ wp_error: error message surfaced

[6] flat-shape params (no nested params key) also work:
✓ flat shape: job completed
✓ flat shape: channel forwarded
✓ flat shape: recipient forwarded
✓ flat shape: message forwarded
✓ flat shape: task scaffolding stripped
✓ flat shape: task_type scaffolding stripped


46 / 46 passed

All assertions passed.
```

Reproduce with: `php tests/dispatch-message-task-smoke.php` from the repo root.

Transport-neutrality confirmation

```
$ grep -iE 'kimaki|discord|slack|telegram|whatsapp|cc-connect' \
inc/Engine/AI/System/Tasks/DispatchMessageTask.php
(zero matches)
```

The only matches in `tests/dispatch-message-task-smoke.php` are inside the banned-list array that powers the assertion itself — not transport coupling in production code.

Lint

`vendor/bin/phpcs inc/Engine/AI/System/Tasks/DispatchMessageTask.php inc/Engine/AI/System/SystemAgentServiceProvider.php tests/dispatch-message-task-smoke.php` is clean (zero findings against the repo's default standard). Per AGENTS.md, no attempt was made to address unrelated pre-existing lint debt on `main`.

Handler config example

An example flow handler_config is documented in #2049:

```json
{
"task": "dispatch_message",
"params": {
"channel": "",
"recipient": "",
"message": "",
"conversation_id": null,
"attachments": [],
"client_context": {},
"metadata": {}
}
}
```

Required input: `channel`, `recipient`, `message`. Everything else passes through to the ability untouched.

Out of scope (per #2049)

  • Admin UI / form-builder for configuring the task — JSON / WP-CLI for now.
  • Migration of existing `agent_call` flows to `dispatch_message` (operational, per-site).

cc <@532385681268408341> when ready for review.

homeboy-ci Bot added 2 commits May 16, 2026 20:52
…essage

Adds the DM-side adapter that lets a scheduled flow trigger an outbound
message through whatever channel runtime is registered against the
agents/dispatch-message ability (agents-api v0.107.0+). Mirrors the
shape of AgentCallTask: thin wrapper, no transport knowledge, canonical
output forwarded into the job result envelope.

Refs #2049
Covers four behaviour paths for the new dispatch_message task:

  1. Source-level registration in SystemAgentServiceProvider and
     transport-neutrality of the task file (no kimaki/discord/slack/etc.
     names leak into the wrapper).
  2. Ability-missing path — wp_get_ability returns null, task fails the
     job with a clear message naming the ability slug and the agents-api
     substrate.
  3. Handler success path — canonical output (sent, channel, recipient,
     message_id, metadata) flows into the job result envelope alongside
     a completed_at timestamp, and the canonical input is forwarded to
     the ability untouched.
  4. Handler WP_Error path — error code + message propagate as a job
     failure.

Also pins the flat-shape passthrough (params on the top-level array)
since both shapes appear in handler_config wiring.

Refs #2049
@chubes4
Copy link
Copy Markdown
Member Author

chubes4 commented May 16, 2026

<@532385681268408341> ready for review — implements #2049, 46/46 smoke assertions passing, lint clean, transport-neutral. Two conventional commits: feat(system-task) + test(system-task). No CHANGELOG / version touched.

@homeboy-ci
Copy link
Copy Markdown
Contributor

homeboy-ci Bot commented May 16, 2026

Homeboy Results — data-machine

Lint

lint — passed

ℹ️ Full options: homeboy docs commands/lint
Deep dive: homeboy lint data-machine --changed-since d69fae3

Test

test — passed

ℹ️ Auto-fix lint issues: homeboy refactor data-machine --from lint --write
ℹ️ Collect coverage: homeboy test data-machine --coverage
ℹ️ Pass args to test runner: homeboy test -- [args]
ℹ️ Full options: homeboy docs commands/test
Deep dive: homeboy test data-machine --changed-since d69fae3

Audit

audit — passed

  • requested_detectors — 125 finding(s)
  • test_coverage — 28 finding(s)
  • intra-method-duplication — 8 finding(s)
  • dead_code — 5 finding(s)
  • dead_guard — 3 finding(s)
  • Directives — 1 finding(s)
  • Retention — 1 finding(s)
  • Tasks — 1 finding(s)
  • Total: 172 finding(s)

Deep dive: homeboy audit data-machine --changed-since d69fae3

Tooling versions
  • Homeboy CLI: homeboy 0.182.0+6049bc7f
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: 9eb4c10
  • Action: unknown@unknown

@chubes4 chubes4 merged commit 0ecd0db into main May 16, 2026
5 checks passed
@chubes4 chubes4 deleted the feat/dispatch-message-task branch May 16, 2026 21:00
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.

feat(system-task): DispatchMessageTask wrapping agents/dispatch-message

1 participant