survos / ai-workflow-bundle
Symfony workflow primitives for async AI preparation, observation, analysis, and publishing.
Package info
github.com/survos/ai-workflow-bundle
Type:symfony-bundle
pkg:composer/survos/ai-workflow-bundle
Fund package maintenance!
Requires
- php: ^8.5
- aws/aws-sdk-php: ^3.388
- survos/claims-bundle: ^2.5
- survos/data-contracts: ^2.5
- survos/kit-bundle: ^2.33
- survos/menu-bundle: ^2.42.7
- survos/workflow-extras-bundle: ^2.42.8
- survos/workflow-messenger-bundle: ^2.42.9
- symfony/ai-agent: ^0.14
- symfony/ai-bundle: ^0.14
- symfony/ai-mistral-platform: ^0.14
- symfony/ai-open-ai-platform: ^0.14
- symfony/dependency-injection: 8.2.*@dev
- symfony/framework-bundle: 8.2.*@dev
- symfony/http-client: 8.2.*@dev
- symfony/messenger: 8.2.*@dev
- symfony/service-contracts: ^3.6
- symfony/twig-bundle: 8.2.*@dev
- symfony/workflow: 8.2.*@dev
- twig/twig: ^3.0|^4.0
Requires (Dev)
- phpunit/phpunit: ^13.0
- survos/tabler-bundle: ^2.42.9
Suggests
- survos/imgproxy-bundle: Signed imgproxy URL generation — implement AiThumbnailProviderInterface using ImgproxyUrlBuilder
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 2.43.1
- 2.42.14
- 2.42.13
- 2.41.9
- 2.34.31
- 2.34.1
- 2.33.2
- 2.33.0
- 2.31.14
- 2.31.12
- 2.31.11
- 2.31.9
- 2.31.8
- 2.28.3
- 2.28.2
- 2.28.1
- 2.26.9
- 2.19.0
- 2.18.20
- 2.18.19
- 2.18.18
- 2.17.0
- 2.15.21
- 2.15.15
- 2.11.4
- 2.11.3
- 2.11.0
- 2.10.19
- 2.10.18
- 2.10.17
- 2.10.16
- 2.10.15
- 2.10.14
- 2.10.13
- 2.10.12
- 2.10.11
- 2.10.10
- 2.10.9
- 2.10.8
- 2.10.7
- 2.10.6
- 2.10.5
- 2.10.4
- 2.10.3
- 2.10.2
- 2.10.1
- 2.10.0
- 2.9.4
- 2.9.3
- 2.9.2
- 2.9.1
- 2.9.0
- 2.8.4
- 2.8.3
- 2.8.2
- 2.8.1
- 2.8.0
- 2.7.23
- 2.7.22
- 2.7.21
- 2.7.20
- 2.7.19
- 2.7.18
- 2.7.17
- 2.7.16
- 2.7.15
- 2.7.14
- 2.7.13
- 2.7.12
- 2.7.11
- 2.7.10
- 2.7.9
- 2.7.8
- 2.7.7
- 2.7.6
- 2.7.5
- 2.7.4
- 2.7.3
- 2.7.2
- 2.7.1
- 2.7.0
- 2.6.0
- 2.5.8
- 2.5.7
- 2.5.6
- 2.5.5
- 2.5.3
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
This package is auto-updated.
Last update: 2026-10-17 15:08:03 UTC
README
Symfony 8.2 workflow primitives for async AI work over any subject.
The bundle defines a small shared lifecycle:
new -> prepared -> observed -> analyzed -> reviewed -> published
The important split is conceptual:
prepare: make source content and context available.observe: create neutral evidence from the source. For images this is usually thumbnail observation plus optional high-resolution reads; for text it may be dense summaries, language, or structure.analyze: apply application meaning to observed evidence and context.review: app-defined approval after analysis. This can be automatic policy, human review, or another app-specific gate.publish: project the result into fields, indexes, exports, webhooks, or other app outputs.
The bundle does not decide what those transitions do. Applications provide workflow listeners, task policy, and publishing behavior.
The bundle may define reusable tasks and prompt templates. Treat those as a prompt/task repository, not app policy: applications still decide which tasks to queue, when to append follow-up tasks, and what publish means.
Core Classes
Workflow\SubjectFlow: native attribute-based workflow definition.Contract\WorkflowSubjectInterface: minimal subject id plus queue/lock shape for entities. Claim subject type defaults to the PHP class name.Task\TaskInterface: callable workflow task that returns claims.Task\TaskResult: claims plus optional follow-up tasks.Task\TaskRegistry: lazy task lookup by name.Task\TaskRunner: consumes one queued task and records claims throughsurvos/claims-bundle.
Task outputs are not stored as opaque JSON result blobs. They are recorded as ClaimRun and Claim rows. Apps can still denormalize claim projections onto their own entities during publish.
Queueing Tasks
Applications queue and run tasks from workflow listeners. Use task constants instead of string literals so built-in task names stay refactorable:
<?php namespace App\Workflow; use App\Entity\GalleryImage; use Doctrine\ORM\EntityManagerInterface; use Survos\AiWorkflowBundle\Task\EnrichFromThumbnailTask; use Survos\AiWorkflowBundle\Task\TaskRunner; use Survos\AiWorkflowBundle\Workflow\SubjectFlow; use Symfony\Component\Workflow\Attribute\AsTransitionListener; use Symfony\Component\Workflow\Event\TransitionEvent; final class GalleryWorkflow { public function __construct( private readonly EntityManagerInterface $entityManager, private readonly TaskRunner $taskRunner, ) { } #[AsTransitionListener(SubjectFlow::WORKFLOW_NAME, SubjectFlow::TRANSITION_PREPARE)] public function onPrepare(TransitionEvent $event): void { $image = $this->getImage($event); if ($image->getWorkflowQueue() === []) { $image->setWorkflowQueue([EnrichFromThumbnailTask::TASK]); } $this->entityManager->flush(); } #[AsTransitionListener(SubjectFlow::WORKFLOW_NAME, SubjectFlow::TRANSITION_OBSERVE)] public function onObserve(TransitionEvent $event): void { $image = $this->getImage($event); $this->taskRunner->runNext($image); $this->entityManager->flush(); } private function getImage(TransitionEvent $event): GalleryImage { $image = $event->getSubject(); \assert($image instanceof GalleryImage); return $image; } }
TaskRunner::runNext() removes one task from the queue, records claims through survos/claims-bundle, and appends any follow-up tasks returned by the task. For image workflows, EnrichFromThumbnailTask::TASK is usually the first observation task; it can append higher-resolution observation tasks such as OcrMistralTask::TASK or TranscribeHandwritingTask::TASK.
Naming
Inside Survos\AiWorkflowBundle, class names intentionally avoid the Ai prefix where the namespace already carries it:
SubjectFlowTaskInterfaceTaskRegistryTaskRunner
Failure Model
There is no failed place in the initial workflow. Failures should be recorded on task runs, claims, or app-specific fields while the subject remains at its current milestone. Apps can add a failure place later if they need one.
Workflow integration
Enable survos/workflow-extras-bundle and survos/workflow-messenger-bundle,
with workflow: ~ in your application configuration. State-bundle is no longer
required. The AI workflow supports subjects implementing PendingStepsInterface;
other workflow subjects, such as media records, retain their own lifecycle.
Doctrine subjects keep a scalar marking property and the usual Symfony marking
store accessors. Existing persisted place values are unchanged.
Configure Messenger transports named ai_subject.prepare, ai_subject.observe,
ai_subject.analyze, ai_subject.review, and ai_subject.publish. Transition
metadata selects these transports explicitly. The application's transport DSNs
control how the jobs are delivered; the bundle does not create queues implicitly.
Observation repeats while observation tasks remain. Analysis begins after observation drains and repeats only while analysis tasks remain. Review waits for analysis to drain; automatic continuation then publishes once. Applications can add guard listeners for human approval or other review policy. Manual review and publish transitions remain repeatable. Pending tasks retain FIFO ordering.
Menu integration uses MenuSlot::ADMIN_NAVBAR_MENU through AsMenuListener.