Agent Task Automation-Action Step (agent_task)
The bundle ships an automation-action step, agent_task, for the Pimcore Copilot bundle's automation actions
(Generic Execution Engine). It is the first consumer of the headless agent task facade and the
reason the concurrency cap below exists. The step registers itself and appears in the step picker automatically
whenever the Copilot bundle is installed, with no configuration in the Copilot bundle needed.
Naming note. "Copilot" here is the Pimcore Copilot bundle (automation actions / Generic Execution Engine), not the GitHub Copilot SDK this bundle's own Core Concepts uses as its LLM adapter. The two are unrelated products that happen to share a name.
The step runs the agent exactly like a Pimcore Studio chat session does - same tools, same permissions - except no
human is watching: it must finish the task itself and call finalize_task exactly once.
Configuration
agent: 'data-management' # Required: agent configuration name
instructions: | # Required: task instructions, in addition to selected elements
Review the selected products and fix any missing SEO meta descriptions.
output_schema: # Optional JSON Schema (written as YAML) the output must validate against
type: object
additionalProperties: false
required: [processed, summary]
properties:
processed: { type: integer }
summary: { type: string }
reviewer: 'jdoe' # Optional Pimcore username who reviews; falls back to the acting user when empty
timeout_seconds: 900 # How long the step waits, including time queued for a free task slot
context_key: 'agent_result' # Job-run context key the result envelope is written under
continue_session_from: '' # Optional: context_key of an earlier agent_task step to resume
-
Writing
output_schema. The whole automation action is YAML, sooutput_schemais written as YAML that maps to a JSON Schema. The bundle parses it to a PHP array and validates the agent'soutputwith opis/json-schema. The example above is equivalent to this JSON Schema:{ "type": "object", "additionalProperties": false, "required": ["processed", "summary"],
"properties": { "processed": { "type": "integer" }, "summary": { "type": "string" } } }Values must be real YAML types (
false, not"false"). A common mistake when editing the schema in the Studio automation-action editor is quoting booleans or strings, which produces an invalid schema and fails the step early. -
revieweris a Pimcore username, not a user id. The step resolves the configured username to a user id when it runs (UserResolverInterface::getByName()). A non-empty but unresolvable username aborts the step. Leaving it empty is valid - the session owner then falls back to the task's acting user, per Agent Tasks → Access and review. (The PHP facade and thepimcore-agent:task:runcommand instead take a numeric user id indesignatedUserId/--reviewer; only this step takes a username, because that is what reads naturally in an automation-action editor.) -
Selection mode. The step processes all of a job run's selected elements (data objects, assets, documents) as one task (
SelectionProcessingMode::ONCE). A separate task per element (FOR_EACH) is not wired up. -
Resuming a prior step's task. Set
continue_session_fromto thecontext_keyof an earlieragent_taskstep in the same job run. The step reads that step's{context_key}__task_idcontext entry and callscontinueTask()instead of starting a fresh task. This is valid only inONCEmode - a shared context key cannot address one of several parallelFOR_EACHtasks. A resuming step still applies its ownoutput_schema(andinstructions); the continuation validatesfinalize_taskagainst the schema configured on the continuing step, never the schema of the step it resumes. -
Concurrency cap.
start()(andcontinueTask()) enforcepimcore_agent.tasks.max_concurrent(default 5) across the whole bundle. While the cap is hit, the step retries every 10 seconds, sharing its owntimeout_secondsbudget with the subsequent wait. Size the Generic Execution Engine worker pool with blocking agent steps in mind. -
Runs end to end, no pause-for-input. Generic Execution Engine steps have no suspend/resume primitive, so the step blocks on
start()(orcontinueTask()) pluswaitFor(), like the built-in webhook step blocks on HTTP. With direct-write tools the whole workflow runs without a human in the loop. With propose tools the step still captures the turn's summary and proposals, but nothing is applied until thereviewer(or a participant with access) approves it in Pimcore Studio. -
Failure and timeout. A
failedresult, or a client-side wait timeout (which also cancels the task), callsthrowUnRecoverableException(); ordinary Generic Execution Engine error handling (STOP_ON_FIRST_ERROR/CONTINUE_ON_ERROR) applies from there. The result envelope is written to the job run's context undercontext_keybefore that happens either way, so later steps and the run history still see it.
The step's own dispatch (AgentTaskStepMessage, #[AsMessageHandler]) is the Generic Execution Engine's normal
messenger path for automation-action steps. It is unrelated to how the task's own settlement publishes
AgentTaskCompletedEvent inline (see
Architecture → Announcing completion).
Related docs
- Agent Tasks - the facade this step consumes, the result envelope it writes to
context_key, and the autonomy-vs-HITL choice that decides how much the step does on its own. - Architecture → Agent Tasks - the state machine, settlement, watchdog, and delegated-access model behind the facade.
- Configuration → Agents → Agent tasks - the
pimcore_agent.tasks.*limits, including the concurrency cap and deadlines. - Troubleshooting → Agent tasks - the
error.reasonvalues a failed step writes into the envelope.