Channels: sender_id + tool context; workflows: ${vars}, foreach, dispatch-message#168
Conversation
|
Directionally this is aligned with what I would want Agents API to own, using Data Machine as the production adoption case. Data Machine already has the big, messy version of this problem: durable flows, scheduled jobs, fan-out, tool execution, channel-ish chat surfaces, approval gates, and long-running automation. From that lens, these primitives are the right kind of substrate:
The part I would want tightened before adopting this for production Data Machine scheduling is the workflow lifecycle contract around cron auto-sync. Right now the new sync hooks What I’d want from Agents API before DM could lean on this directly:
So I like the AS bridge pattern, and it does not conflict with Data Machine. I just wouldn’t want the auto-sync story to stop at One adjacent architectural note: the tool-context change is solving a real need, but I’d prefer required tool args to be satisfied by explicit context mappings/defaults rather than broad ambient context key matching. That keeps sensitive parameters auditable when a runtime like DM starts delegating more tool execution to Agents API. |
WordPress 7.0 has not been released. Drop to 6.7, which is the oldest currently released line that ships the Abilities API hooks agents-api relies on. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two coupled substrate changes that let WhatsApp/wacli channels deliver caller identity to tool calls without asking the model to invent it. WP_Agent_Channel gains an extract_sender_id() hook (default null) and threads the value into WP_Agent_External_Message::sender_id. The canonical agents/chat ability advertises the new client_context.sender_id field in its input schema so external dispatchers can pass it. WP_Agent_Tool_Execution_Core now merges the tool context into the parameter set BEFORE validating required fields. Previously a required parameter that the channel could satisfy via context was rejected at the validation step. Tools whose schema marks user_phone as required can now be invoked from a channel-driven turn as long as the runtime context carries it. Smoke tests updated to cover the new external-message field, the schema property, and the context-fills-required path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Substrate features unlocked by building real consumers (penca-style
product) on top of the workflow engine.
Workflow bindings: \${vars.x.y} now resolves against scoped runtime
values populated inside foreach iterations. Lets a foreach body bind
ability arguments to the current iteration's item.
Workflow runner: new foreach step type. Iterates a bound array (e.g.
\${steps.find_matches.output.matches}) under a scoped name (`as`) and
runs an inner step list per item, with optional continue_on_error.
Workflow spec validator: nested step paths no longer prefix steps.
twice. Errors emerge as workflow.steps.0.steps.1 instead of
workflow.steps.0.steps.steps.1.
register-workflow-bridge-sync: action-scheduler bridge auto-syncs
workflow cron triggers when wp_register_workflow() fires. Drops the
need for consumers to wire schedule lifecycle themselves.
agents/dispatch-message ability: substrate-side ability that
workflow `dispatch` steps invoke to send outbound channel messages.
Validates channel/recipient/message, supports attachments, and runs
through a wp_agent_dispatch_message_handler filter so consumers
(openclaWP, custom plugins) provide the actual transport. Permission
defaults to manage_options with an agents_dispatch_message_permission
filter for narrower gating.
Smoke tests cover all primitives: vars resolution, foreach iteration,
spec validator path fix, dispatch-message wiring (handler, permission,
schema).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit dropped Requires at least from a fictional 7.0 to 6.7, but the Abilities API that this substrate registers against via wp_register_ability() did not land in core until WordPress 6.9. 6.7 was still too low to guarantee the API surface is present. Set Requires at least to 6.9, the actual minimum version that ships wp_register_ability() in core. Add Tested up to: 6.9 to declare forward-looking compatibility against the current stable line; bump this with each new WP release after a smoke pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WordPress 7.0-RC3 is the in-development release the substrate is written against (it ships the Abilities API surface this plugin needs). The previous bumps in this branch were mistakes triggered by running stable WP locally; the fix is to run a 7.0 dev build, not weaken the substrate floor. Tested up to: 7.0 aligns with Requires at least. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`wp_agent_workflow_registered` only covers code-defined workflows added to the in-memory registry during plugin boot. Durable workflows backed by a WP_Agent_Workflow_Store need their own event surface so consumers can react to saved / deleted / disabled / enabled state changes outside the request boot path. - Add WP_Agent_Workflow_Lifecycle helper that fires canonical hooks for saved, deleted, disabled, and enabled events. - Document the lifecycle contract on the WP_Agent_Workflow_Store interface (implementations call the helper after each store op). - Add WP_Agent_Workflow_Action_Scheduler_Bridge::sync() that unschedules every existing AS action for the workflow id before re-registering cron triggers, so updates that drop a cron trigger don't leak stale schedules. - Wire the bridge-sync subscriber to react to saved/deleted/disabled/ enabled events, distinct from the existing registered hook. - Add tests/workflow-lifecycle-smoke.php. Addresses review feedback on PR #168: durable workflows need lifecycle events independent of in-memory registration so AS stays in sync with create/update/delete and unschedules stale hooks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Broad ambient context-key matching let any host-supplied context value silently satisfy a tool's required parameter just by sharing a name. That keeps sensitive parameters un-auditable when a runtime delegates tool execution to substrate code. - WP_Agent_Tool_Parameters::buildParameters now only pulls context values for slots explicitly declared in the tool's `client_context_bindings` field. Caller-supplied parameters still win over bindings. - Declarations accept either an associative form (parameter_name => context_key, allows renaming) or a flat list shorthand for same-name bindings. - Empty / null context values are skipped so they can't silently satisfy a required-parameter check. - Adapter in tool-runtime-smoke now reads ambient context (`request_id`, `agent_id`) from the executor's `$context` arg rather than expecting them to be merged into `$tool_call['parameters']`. Adds coverage for rename bindings and confirms undeclared context keys cannot satisfy a required parameter. Addresses review feedback on PR #168: keep context-to-parameter injection explicit so authors of sensitive abilities know exactly which context keys can reach a required argument. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
55a5478 to
5dc4195
Compare
|
Thanks for the close read. Pushed two follow-ups: f32d2c8 introduces 5dc4195 drops the broad ambient context-key matching for required tool args. Tools now opt in via Both covered by smoke tests ( |
|
Architecture concerns from the Data Machine adoption lens are resolved for me. The durable lifecycle hooks + Only thing from my side: fix the current lint failure, then let 'er rip. |
Homeboy/WPCS reported double-arrow and equals-sign alignment violations introduced by the new `agents/dispatch-message` schema (where `conversation_id` is the longest key in the `properties` map) and the `foreach` step nested-output bookkeeping in the workflow runner. - `register-agents-dispatch-message-ability.php`: pad the six shorter property keys by one space so every `=>` lines up with the `conversation_id` row. - `class-wp-agent-workflow-runner.php`: pad the `$step_outputs[...]` assignment by two spaces so its `=` aligns with the wider `$iteration_context['steps'][...]` assignment below it. Pure whitespace; smoke suite still passes (all 1100+ assertions). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds two layers of substrate primitives that consumers (WhatsApp adapters, multi-step workflows, message-broadcast use-cases) were repeatedly reaching past:
Channels + tool context
WP_Agent_Channel::extract_sender_id()extension hook so adapters can expose the user's external id (WhatsApp number, Slack user, etc.) to the runtime.client_context.sender_idplumbed into theagents/chatschema so abilities can be authored against the canonical client context shape.user_phonefromsender_id) satisfy an ability's required arg without forcing every channel to duplicate that logic per turn.Workflow primitives
\${vars.*}bindings alongside the existing\${steps.*.output.*}syntax, for hoisting workflow-level constants.foreachstep type so a workflow can fan a single step over an array (e.g. "for each pending prediction, score it").New ability + auto-sync
Smoke tests for all of the above under `tests/`.
Test plan