@bluefly/openstandardagents 0.2.5-RC → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devfile.yaml +1 -1
- package/.env.example +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +40 -0
- package/.github/workflows/dependabot-comment.yml +34 -0
- package/.github/workflows/pr-comment.yml +33 -0
- package/.husky/pre-commit +5 -0
- package/.kiro/config.json +21 -0
- package/.kiro/settings/mcp.json +61 -0
- package/.kiro/specs/scripts-migration-api-first/design.md +883 -0
- package/.kiro/specs/scripts-migration-api-first/requirements.md +165 -0
- package/.kiro/specs/scripts-migration-api-first/tasks.md +539 -0
- package/.kiro/specs/{website-design-audit → website-brand-identity}/design.md +381 -0
- package/.kiro/specs/{website-design-audit → website-brand-identity}/requirements.md +88 -0
- package/.kiro/specs/website-brand-identity/tasks.md +981 -0
- package/.version.json +2 -2
- package/.wiki-config.json +24 -0
- package/CHANGELOG.md +34 -18
- package/CODEOWNERS +75 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +176 -239
- package/bin/ossa-dev +42 -0
- package/bin/ossa-export +32 -0
- package/bin/ossa-generate +60 -0
- package/bin/ossa-health +40 -0
- package/bin/ossa-init +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/repositories/schema.repository.d.ts +6 -1
- package/dist/repositories/schema.repository.d.ts.map +1 -1
- package/dist/repositories/schema.repository.js +63 -36
- package/dist/repositories/schema.repository.js.map +1 -1
- package/dist/services/github-sync/github-client.d.ts +14 -0
- package/dist/services/github-sync/github-client.d.ts.map +1 -0
- package/dist/services/github-sync/github-client.js +41 -0
- package/dist/services/github-sync/github-client.js.map +1 -0
- package/dist/services/github-sync/gitlab-client.d.ts +17 -0
- package/dist/services/github-sync/gitlab-client.d.ts.map +1 -0
- package/dist/services/github-sync/gitlab-client.js +42 -0
- package/dist/services/github-sync/gitlab-client.js.map +1 -0
- package/dist/services/github-sync/schemas.d.ts +46 -0
- package/dist/services/github-sync/schemas.d.ts.map +1 -0
- package/dist/services/github-sync/schemas.js +36 -0
- package/dist/services/github-sync/schemas.js.map +1 -0
- package/dist/services/github-sync/sync.service.d.ts +27 -0
- package/dist/services/github-sync/sync.service.d.ts.map +1 -0
- package/dist/services/github-sync/sync.service.js +99 -0
- package/dist/services/github-sync/sync.service.js.map +1 -0
- package/dist/services/migration.service.d.ts +4 -3
- package/dist/services/migration.service.d.ts.map +1 -1
- package/dist/services/migration.service.js +11 -10
- package/dist/services/migration.service.js.map +1 -1
- package/dist/services/release-automation/release.service.js +1 -1
- package/dist/services/release-automation/release.service.js.map +1 -1
- package/dist/services/release-automation/schemas/release.schema.js +1 -1
- package/dist/services/runtime/claude/capability-mapper.d.ts +84 -0
- package/dist/services/runtime/claude/capability-mapper.d.ts.map +1 -0
- package/dist/services/runtime/claude/capability-mapper.js +245 -0
- package/dist/services/runtime/claude/capability-mapper.js.map +1 -0
- package/dist/services/runtime/claude/claude-adapter.d.ts +80 -0
- package/dist/services/runtime/claude/claude-adapter.d.ts.map +1 -0
- package/dist/services/runtime/claude/claude-adapter.js +287 -0
- package/dist/services/runtime/claude/claude-adapter.js.map +1 -0
- package/dist/services/runtime/claude/manifest-parser.d.ts +77 -0
- package/dist/services/runtime/claude/manifest-parser.d.ts.map +1 -0
- package/dist/services/runtime/claude/manifest-parser.js +169 -0
- package/dist/services/runtime/claude/manifest-parser.js.map +1 -0
- package/dist/services/runtime/claude/types.d.ts +115 -0
- package/dist/services/runtime/claude/types.d.ts.map +1 -0
- package/dist/services/runtime/claude/types.js +6 -0
- package/dist/services/runtime/claude/types.js.map +1 -0
- package/dist/services/validation.service.d.ts.map +1 -1
- package/dist/services/validation.service.js +12 -1
- package/dist/services/validation.service.js.map +1 -1
- package/dist/spec/v0.2.4/ossa-0.2.4.schema.json +85 -208
- package/dist/spec/v0.2.6/CHANGELOG.md +401 -0
- package/dist/spec/v0.2.6/README.md +72 -0
- package/dist/spec/v0.2.6/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/dist/spec/v0.2.6/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/dist/spec/{v0.2.4/ossa-0.2.4-dev.schema.json → v0.2.6/ossa-0.2.6.schema.json} +128 -38
- package/dist/spec/v0.2.6/ossa-0.2.6.yaml +581 -0
- package/dist/spec/v0.2.6-dev/CHANGELOG.md +164 -0
- package/dist/spec/v0.2.6-dev/README.md +75 -0
- package/dist/spec/v0.2.6-dev/migrations/v0.2.2-to-v0.2.3.md +343 -0
- package/dist/spec/v0.2.6-dev/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/dist/spec/v0.2.6-dev/ossa-0.2.5.yaml +581 -0
- package/dist/spec/v0.2.6-dev/ossa-0.2.6-dev.yaml +448 -0
- package/dist/spec/v0.2.7/core/agentgraph.md +324 -0
- package/dist/spec/v0.2.7/resources/agentgraph.yaml +135 -0
- package/dist/spec/v0.2.8/CHANGELOG.md +401 -0
- package/dist/spec/v0.2.8/README.md +72 -0
- package/dist/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/dist/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/dist/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
- package/dist/spec/v0.2.8/ossa-0.2.8.schema.json +3153 -0
- package/dist/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/version.d.ts +68 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +156 -0
- package/dist/utils/version.js.map +1 -0
- package/docs/brand-guide/01-brand-overview.md +37 -0
- package/docs/brand-guide/02-logo-usage.md +43 -0
- package/docs/brand-guide/03-color-palette.md +70 -0
- package/docs/brand-guide/04-typography.md +82 -0
- package/docs/brand-guide/05-voice-and-tone.md +108 -0
- package/docs/brand-guide/06-visual-elements.md +137 -0
- package/docs/brand-guide/07-application-examples.md +153 -0
- package/docs/brand-guide/OssaLogo/OssA_Logo.svg +21 -0
- package/docs/brand-guide/OssaLogo/brand.af +0 -0
- package/docs/brand-guide/README.md +107 -0
- package/docs/comparison.md +315 -0
- package/docs/operations/automation-roadmap.md +245 -0
- package/docs/operations/github-sync-strategy.md +357 -0
- package/eslint-report.json +1 -0
- package/examples/adk-integration/code-review-workflow.yml +1 -1
- package/examples/adk-integration/customer-support.yml +1 -1
- package/examples/adk-integration/data-pipeline.yml +1 -1
- package/examples/advanced/workflows/hybrid-model-strategy.yaml +1 -1
- package/examples/agent-manifests/critics/critic-agent.yaml +1 -1
- package/examples/agent-manifests/governors/governor-agent.yaml +1 -1
- package/examples/agent-manifests/integrators/integrator-agent.yaml +1 -1
- package/examples/agent-manifests/judges/judge-agent.yaml +1 -1
- package/examples/agent-manifests/monitors/monitor-agent.yaml +1 -1
- package/examples/agent-manifests/orchestrators/orchestrator-agent.yaml +1 -1
- package/examples/agent-manifests/sample-compliant-agent.yaml +1 -1
- package/examples/agent-manifests/workers/worker-agent.yaml +1 -1
- package/examples/anthropic/claude-assistant.ossa.json +5 -4
- package/examples/autogen/multi-agent.ossa.json +6 -4
- package/examples/claude-code/code-reviewer.ossa.yaml +78 -0
- package/examples/claude-code/ossa-validator.ossa.yaml +80 -0
- package/examples/common_npm/agent-router.ossa.yaml +1 -0
- package/examples/common_npm/agent-router.v0.2.2.ossa.yaml +1 -1
- package/examples/crewai/research-team.ossa.json +14 -5
- package/examples/cursor/code-review-agent.ossa.json +21 -6
- package/examples/drupal/gitlab-ml-recommender.ossa.yaml +1 -0
- package/examples/drupal/gitlab-ml-recommender.v0.2.2.ossa.yaml +1 -1
- package/examples/extensions/drupal-v1.yml +1 -1
- package/examples/extensions/kagent-v1.yml +1 -1
- package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
- package/examples/integration-patterns/agent-to-agent-orchestration.ossa.yaml +4 -4
- package/examples/kagent/compliance-validator.ossa.yaml +1 -1
- package/examples/kagent/cost-optimizer.ossa.yaml +1 -1
- package/examples/kagent/documentation-agent.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter-v1.ossa.yaml +1 -0
- package/examples/kagent/k8s-troubleshooter-v1.v0.2.2.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter.ossa.yaml +1 -1
- package/examples/kagent/security-scanner.ossa.yaml +1 -1
- package/examples/langchain/chain-agent.ossa.json +21 -5
- package/examples/langflow/workflow-agent.ossa.json +2 -3
- package/examples/langgraph/state-machine-agent.ossa.json +2 -3
- package/examples/llamaindex/rag-agent.ossa.json +2 -3
- package/examples/migration-guides/from-langchain-to-ossa.yaml +4 -4
- package/examples/multi-agent/README.md +74 -0
- package/examples/multi-agent/conditional-router.ossa.yaml +42 -0
- package/examples/multi-agent/parallel-execution.ossa.yaml +54 -0
- package/examples/multi-agent/sequential-pipeline.ossa.yaml +45 -0
- package/examples/openai/basic-agent.ossa.yaml +1 -1
- package/examples/openai/multi-tool-agent.ossa.json +33 -10
- package/examples/openai/swarm-agent.ossa.json +18 -5
- package/examples/production/document-analyzer-openai.yml +1 -1
- package/examples/quickstart/support-agent.ossa.yaml +1 -1
- package/examples/spec-examples/audit-agent.yml +1 -1
- package/examples/spec-examples/chat-agent.yml +1 -1
- package/examples/spec-examples/compliance-agent.yml +1 -1
- package/examples/spec-examples/monitoring-agent.yml +1 -1
- package/examples/spec-examples/workflow-agent.yml +1 -1
- package/examples/templates/ossa-compliance.yaml +1 -1
- package/examples/vercel/edge-agent.ossa.json +5 -4
- package/gl-code-quality-report.json +62 -0
- package/llms-ctx-full.txt +39 -0
- package/llms-ctx.txt +39 -0
- package/llms.txt +47 -0
- package/openapi/github-sync.yaml +115 -0
- package/package.json +26 -4
- package/scripts/README.md +103 -0
- package/scripts/auto-rebase-mrs.ts +106 -0
- package/scripts/batch-dependabot.sh +57 -0
- package/scripts/configure-gitlab-branch-protection.ts +95 -0
- package/scripts/create-issue-helper.ts +238 -0
- package/scripts/create-milestone-issue.ts +73 -0
- package/scripts/eslint-to-codequality.cjs +34 -0
- package/scripts/fix-schema-formats.js +82 -0
- package/scripts/generate-agents-catalog.ts +77 -0
- package/scripts/generate-api-docs.ts +218 -0
- package/scripts/generate-cli-docs.ts +410 -0
- package/scripts/generate-config-docs.ts +109 -0
- package/scripts/generate-errors-docs.ts +76 -0
- package/scripts/generate-examples-docs.ts +99 -0
- package/scripts/generate-llms-ctx.sh +17 -0
- package/scripts/generate-schema-docs.ts +317 -0
- package/scripts/generate-types-docs.ts +48 -0
- package/scripts/lowercase-docs.ts +43 -0
- package/scripts/manage-milestone-mrs.ts +279 -0
- package/scripts/rebase-all-mrs.sh +75 -0
- package/scripts/sync-github-pr.sh +48 -0
- package/scripts/sync-version.js +32 -0
- package/scripts/sync-wiki.sh +50 -0
- package/scripts/validate-all.js +127 -0
- package/scripts/validate-schema.ts +2 -1
- package/spec/v0.2.4/ossa-0.2.4.schema.json +85 -208
- package/spec/v0.2.6/CHANGELOG.md +401 -0
- package/spec/v0.2.6/README.md +72 -0
- package/spec/v0.2.6/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/spec/v0.2.6/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/spec/{v0.2.4/ossa-0.2.4-dev.schema.json → v0.2.6/ossa-0.2.6.schema.json} +128 -38
- package/spec/v0.2.6/ossa-0.2.6.yaml +581 -0
- package/spec/v0.2.6-dev/CHANGELOG.md +164 -0
- package/spec/v0.2.6-dev/README.md +75 -0
- package/spec/v0.2.6-dev/migrations/v0.2.2-to-v0.2.3.md +343 -0
- package/spec/v0.2.6-dev/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/spec/v0.2.6-dev/ossa-0.2.5.yaml +581 -0
- package/spec/v0.2.6-dev/ossa-0.2.6-dev.yaml +448 -0
- package/spec/v0.2.7/core/agentgraph.md +324 -0
- package/spec/v0.2.7/resources/agentgraph.yaml +135 -0
- package/spec/v0.2.8/CHANGELOG.md +401 -0
- package/spec/v0.2.8/README.md +72 -0
- package/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
- package/spec/v0.2.8/ossa-0.2.8.schema.json +3153 -0
- package/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
- package/test-results/junit.xml +299 -0
- package/.kiro/specs/agent-buildkit-templates/design.md +0 -495
- package/.kiro/specs/agent-buildkit-templates/requirements.md +0 -165
- package/.kiro/specs/kiro-ide-supercharger/README.md +0 -202
- package/.kiro/specs/kiro-ide-supercharger/design.md +0 -1005
- package/.kiro/specs/kiro-ide-supercharger/requirements.md +0 -141
- package/.kiro/specs/kiro-ide-supercharger/tasks.md +0 -507
- package/bin/validate-ossa-0.2.5-RC.ts +0 -244
- package/docs/issue-19-completion-summary.md +0 -648
- package/docs/issue-19-validation.md +0 -351
- package/scripts/lib/exec.ts +0 -37
- package/scripts/lib/file-ops.ts +0 -58
- package/scripts/lib/version.ts +0 -83
- package/website/.lighthouserc.ts +0 -24
- package/website/.prettierrc +0 -10
- package/website/Dockerfile +0 -30
- package/website/app/about/page.tsx +0 -295
- package/website/app/blog/[slug]/page.tsx +0 -208
- package/website/app/blog/page.tsx +0 -249
- package/website/app/design-guide/page.tsx +0 -511
- package/website/app/docs/[[...slug]]/page.tsx +0 -847
- package/website/app/docs/core-concepts/project-structure/page.tsx +0 -349
- package/website/app/ecosystem/page.tsx +0 -375
- package/website/app/examples/page.tsx +0 -133
- package/website/app/globals.scss +0 -135
- package/website/app/layout.tsx +0 -106
- package/website/app/license/page.tsx +0 -183
- package/website/app/not-found.tsx +0 -18
- package/website/app/page.tsx +0 -474
- package/website/app/playground/page.tsx +0 -487
- package/website/app/robots.ts +0 -19
- package/website/app/rss.xml/route.ts +0 -74
- package/website/app/schema/page.tsx +0 -1001
- package/website/app/sitemap.ts +0 -56
- package/website/app/specification/page.tsx +0 -287
- package/website/components/InstallCommand.tsx +0 -96
- package/website/components/Logo.tsx +0 -97
- package/website/components/StructuredData.tsx +0 -65
- package/website/components/docs/DocsSearch.tsx +0 -104
- package/website/components/docs/DocsSidebar.tsx +0 -155
- package/website/components/docs/MarkdownContent.tsx +0 -401
- package/website/components/docs/VersionSelector.tsx +0 -105
- package/website/components/examples/ExamplesViewer.tsx +0 -293
- package/website/components/layout/Footer.tsx +0 -116
- package/website/components/layout/Header.tsx +0 -168
- package/website/components/schema/SchemaComponentsAccordion.tsx +0 -84
- package/website/components/schema/SchemaExplorer.tsx +0 -213
- package/website/content/blog/OpenAPI-AI-Agents-Standard.md +0 -285
- package/website/content/blog/Why-Formal-Standards-Matter-Now.md +0 -198
- package/website/content/blog/gitlab-kubernetes-agent-ecosystem.md +0 -286
- package/website/content/blog/introducing-ossa-framework.md +0 -328
- package/website/content/blog/ossa-production-results.md +0 -279
- package/website/content/blog/welcome-to-ossa.md +0 -43
- package/website/content/blog/why-ai-agents-need-open-standard.md +0 -98
- package/website/content/docs/00-HOME.md +0 -153
- package/website/content/docs/AIFlow-Framework-Integration-with-OSSA.md +0 -107
- package/website/content/docs/Examples.md +0 -71
- package/website/content/docs/OpenAPI-Extensions.md +0 -934
- package/website/content/docs/adapters/openai-adapter.md +0 -693
- package/website/content/docs/architecture/execution-flow.md +0 -335
- package/website/content/docs/architecture/multi-agent-systems.md +0 -737
- package/website/content/docs/architecture/overview.md +0 -121
- package/website/content/docs/architecture/stack-integration.md +0 -461
- package/website/content/docs/changelog.md +0 -246
- package/website/content/docs/contributing.md +0 -599
- package/website/content/docs/core-concepts/Project-Structure.md +0 -348
- package/website/content/docs/ecosystem/framework-support.md +0 -819
- package/website/content/docs/ecosystem/overview.md +0 -366
- package/website/content/docs/examples/AIFlow-Framework-Integration-with-OSSA.md +0 -107
- package/website/content/docs/examples/Migration-Guides.md +0 -214
- package/website/content/docs/for-audiences/Architects.md +0 -224
- package/website/content/docs/for-audiences/Developers.md +0 -220
- package/website/content/docs/for-audiences/Enterprises.md +0 -256
- package/website/content/docs/for-audiences/Students-Researchers.md +0 -122
- package/website/content/docs/getting-started/5-Minute-Overview.md +0 -85
- package/website/content/docs/getting-started/First-Agent.md +0 -196
- package/website/content/docs/getting-started/Hello-World.md +0 -184
- package/website/content/docs/getting-started/Installation.md +0 -155
- package/website/content/docs/getting-started/index.md +0 -92
- package/website/content/docs/getting-started/running-agents.md +0 -309
- package/website/content/docs/getting-started.md +0 -91
- package/website/content/docs/integrations/aiflow.md +0 -104
- package/website/content/docs/integrations/drupal.md +0 -105
- package/website/content/docs/migration-guides/00-INDEX.md +0 -76
- package/website/content/docs/migration-guides/README.md +0 -133
- package/website/content/docs/migration-guides/agent-schema-comparison.md +0 -232
- package/website/content/docs/migration-guides/anthropic-mcp-to-ossa.md +0 -1750
- package/website/content/docs/migration-guides/crewai-to-ossa.md +0 -274
- package/website/content/docs/migration-guides/drupal-eca-to-ossa.md +0 -2017
- package/website/content/docs/migration-guides/general-agent-schema.yml +0 -247
- package/website/content/docs/migration-guides/index.md +0 -133
- package/website/content/docs/migration-guides/langchain-to-ossa.md +0 -1714
- package/website/content/docs/migration-guides/langflow-to-ossa.md +0 -2075
- package/website/content/docs/migration-guides/migration-manifest.json +0 -64
- package/website/content/docs/migration-guides/openai-to-ossa.md +0 -1202
- package/website/content/docs/openapi-extensions/examples.md +0 -550
- package/website/content/docs/openapi-extensions/index.md +0 -551
- package/website/content/docs/openapi-extensions/operation-extensions.md +0 -457
- package/website/content/docs/openapi-extensions/root-extensions.md +0 -410
- package/website/content/docs/ossa-compliant-badge.md +0 -251
- package/website/content/docs/pre-release/index.md +0 -175
- package/website/content/docs/quick-reference.md +0 -17
- package/website/content/docs/readme.md +0 -35
- package/website/content/docs/schema-reference/agent-spec.md +0 -406
- package/website/content/docs/schema-reference/autonomy.md +0 -568
- package/website/content/docs/schema-reference/constraints.md +0 -543
- package/website/content/docs/schema-reference/index.md +0 -176
- package/website/content/docs/schema-reference/llm-config.md +0 -445
- package/website/content/docs/schema-reference/observability.md +0 -654
- package/website/content/docs/schema-reference/ossa-manifest.md +0 -309
- package/website/content/docs/schema-reference/taxonomy.md +0 -509
- package/website/content/docs/schema-reference/tools.md +0 -628
- package/website/content/docs/templates/blog-post.md +0 -43
- package/website/content/docs/use-cases/00-index.md +0 -395
- package/website/content/docs/use-cases/cicd-code-review.md +0 -1236
- package/website/content/docs/use-cases/customer-support.md +0 -1234
- package/website/content/docs/use-cases/enterprise-compliance.md +0 -1208
- package/website/content/docs/use-cases/research-multi-agent.md +0 -1161
- package/website/content/docs/versioning.md +0 -288
- package/website/lib/version.ts +0 -35
- package/website/lib/versions.json +0 -78
- package/website/next.config.ts +0 -18
- package/website/nginx.conf +0 -32
- package/website/package-lock.json +0 -9679
- package/website/package.json +0 -59
- package/website/postcss.config.mjs +0 -9
- package/website/scripts/fetch-versions.js +0 -166
- package/website/scripts/generate-examples-index.js +0 -163
- package/website/scripts/merge-docs-to-wiki.ts +0 -207
- package/website/scripts/sync-version.js +0 -72
- package/website/scripts/sync-wiki.ts +0 -322
- package/website/scripts/upload-wiki.ts +0 -199
- package/website/styles/_variables.scss +0 -36
- package/website/tailwind.config.ts +0 -136
- /package/dist/spec/v0.2.4/{ossa-0.2.4-dev.yaml → ossa-0.2.4.yaml} +0 -0
- /package/spec/v0.2.4/{ossa-0.2.4-dev.yaml → ossa-0.2.4.yaml} +0 -0
|
@@ -1,2017 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Drupal ECA to OSSA"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Drupal ECA to OSSA Migration Guide
|
|
6
|
-
|
|
7
|
-
> **Comprehensive guide for converting Drupal ECA (Event-Condition-Action) rules to OSSA (Open Standard for Smart & Scalable Agents) agents**
|
|
8
|
-
|
|
9
|
-
## Table of Contents
|
|
10
|
-
|
|
11
|
-
1. [Overview](#overview)
|
|
12
|
-
2. [Conceptual Mapping](#conceptual-mapping)
|
|
13
|
-
3. [Architecture Comparison](#architecture-comparison)
|
|
14
|
-
4. [Migration Patterns](#migration-patterns)
|
|
15
|
-
5. [Example Migrations](#example-migrations)
|
|
16
|
-
6. [Integration Strategies](#integration-strategies)
|
|
17
|
-
7. [Best Practices](#best-practices)
|
|
18
|
-
8. [Troubleshooting](#troubleshooting)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Overview
|
|
23
|
-
|
|
24
|
-
### Why Migrate from ECA to OSSA?
|
|
25
|
-
|
|
26
|
-
Drupal's ECA module provides powerful event-driven automation for site builders, but OSSA agents offer significant advantages for enterprise systems:
|
|
27
|
-
|
|
28
|
-
**ECA Strengths:**
|
|
29
|
-
- Visual BPMN-based workflow design
|
|
30
|
-
- Deep Drupal integration
|
|
31
|
-
- No-code/low-code approach
|
|
32
|
-
- Site builder friendly
|
|
33
|
-
|
|
34
|
-
**OSSA Advantages:**
|
|
35
|
-
- **Portability**: Framework-agnostic, works beyond Drupal
|
|
36
|
-
- **Scalability**: Distributed agent architecture with K8s/Docker support
|
|
37
|
-
- **Composability**: Multi-agent coordination and swarm orchestration
|
|
38
|
-
- **Observability**: Built-in tracing, metrics, and monitoring
|
|
39
|
-
- **AI-Native**: LLM integration for intelligent decision-making
|
|
40
|
-
- **Enterprise-Ready**: Compliance, security policies, and audit logging
|
|
41
|
-
|
|
42
|
-
### When to Migrate
|
|
43
|
-
|
|
44
|
-
Consider migrating when:
|
|
45
|
-
- Workflows extend beyond Drupal boundaries
|
|
46
|
-
- Need for distributed processing or microservices
|
|
47
|
-
- Require advanced orchestration (multi-agent, swarms)
|
|
48
|
-
- AI/LLM integration is desired
|
|
49
|
-
- Enterprise compliance standards must be met
|
|
50
|
-
- Scaling beyond single Drupal instance
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Conceptual Mapping
|
|
55
|
-
|
|
56
|
-
### ECA → OSSA Translation Matrix
|
|
57
|
-
|
|
58
|
-
| ECA Component | OSSA Equivalent | Mapping Notes |
|
|
59
|
-
|--------------|----------------|---------------|
|
|
60
|
-
| **Event** | Capability trigger + Integration endpoint | Events become API endpoints that agents listen to |
|
|
61
|
-
| **Condition** | Input schema validation + Policy constraints | Conditions are enforced via JSON Schema and policies |
|
|
62
|
-
| **Action** | Agent capability | Actions become agent capabilities with defined schemas |
|
|
63
|
-
| **Model** | Agent manifest | BPMN models become YAML/JSON agent definitions |
|
|
64
|
-
| **Plugin** | Agent dependency | Plugins become required/optional agent dependencies |
|
|
65
|
-
| **Token** | Context data | Tokens map to input/output data passed between capabilities |
|
|
66
|
-
| **State** | Monitoring + Integration state | Persistent state managed via monitoring and external stores |
|
|
67
|
-
|
|
68
|
-
### Key Differences
|
|
69
|
-
|
|
70
|
-
#### ECA: Sequential Event Processing
|
|
71
|
-
```
|
|
72
|
-
Event → Condition Check → Action Execution
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
#### OSSA: Capability-Based Agent Response
|
|
76
|
-
```
|
|
77
|
-
Trigger (HTTP/gRPC) → Agent Capability → Schema Validation → Policy Check → Execute → Monitor
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Architecture Comparison
|
|
83
|
-
|
|
84
|
-
### ECA Architecture (Drupal-Centric)
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
┌─────────────────────────────────────┐
|
|
88
|
-
│ Drupal Event System │
|
|
89
|
-
│ (hook_entity_presave, form_submit) │
|
|
90
|
-
└───────────────┬─────────────────────┘
|
|
91
|
-
│
|
|
92
|
-
▼
|
|
93
|
-
┌─────────────────────────────────────┐
|
|
94
|
-
│ ECA Event Listener │
|
|
95
|
-
└───────────────┬─────────────────────┘
|
|
96
|
-
│
|
|
97
|
-
▼
|
|
98
|
-
┌─────────────────────────────────────┐
|
|
99
|
-
│ Condition Evaluation │
|
|
100
|
-
│ (Field comparison, role check) │
|
|
101
|
-
└───────────────┬─────────────────────┘
|
|
102
|
-
│
|
|
103
|
-
▼
|
|
104
|
-
┌─────────────────────────────────────┐
|
|
105
|
-
│ Action Execution │
|
|
106
|
-
│ (Save entity, send email) │
|
|
107
|
-
└─────────────────────────────────────┘
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### OSSA Architecture (Distributed)
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
┌─────────────────────────────────────┐
|
|
114
|
-
│ External Trigger Sources │
|
|
115
|
-
│ (Drupal hooks, API calls, events) │
|
|
116
|
-
└───────────────┬─────────────────────┘
|
|
117
|
-
│
|
|
118
|
-
▼
|
|
119
|
-
┌─────────────────────────────────────┐
|
|
120
|
-
│ OSSA Agent Integration Layer │
|
|
121
|
-
│ (HTTP/gRPC endpoints) │
|
|
122
|
-
└───────────────┬─────────────────────┘
|
|
123
|
-
│
|
|
124
|
-
▼
|
|
125
|
-
┌─────────────────────────────────────┐
|
|
126
|
-
│ Agent Capabilities │
|
|
127
|
-
│ + Input Schema Validation │
|
|
128
|
-
│ + Policy Enforcement │
|
|
129
|
-
│ + LLM Processing (optional) │
|
|
130
|
-
└───────────────┬─────────────────────┘
|
|
131
|
-
│
|
|
132
|
-
▼
|
|
133
|
-
┌─────────────────────────────────────┐
|
|
134
|
-
│ Monitoring & Observability │
|
|
135
|
-
│ (Traces, metrics, health checks) │
|
|
136
|
-
└─────────────────────────────────────┘
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Migration Patterns
|
|
142
|
-
|
|
143
|
-
### Pattern 1: ECA Events → OSSA Triggers
|
|
144
|
-
|
|
145
|
-
**ECA Event:**
|
|
146
|
-
```yaml
|
|
147
|
-
# ECA Model (conceptual)
|
|
148
|
-
events:
|
|
149
|
-
- event: entity:presave:node:article
|
|
150
|
-
bundle: article
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
**OSSA Agent (Webhook Integration):**
|
|
154
|
-
```yaml
|
|
155
|
-
ossaVersion: "0.2.5-RC"
|
|
156
|
-
agent:
|
|
157
|
-
id: drupal-content-handler
|
|
158
|
-
name: Drupal Content Handler Agent
|
|
159
|
-
version: 1.0.0
|
|
160
|
-
role: integration
|
|
161
|
-
|
|
162
|
-
capabilities:
|
|
163
|
-
- name: handle_article_presave
|
|
164
|
-
description: Process article before saving
|
|
165
|
-
input_schema:
|
|
166
|
-
type: object
|
|
167
|
-
required: [entity_type, entity_id, bundle, field_data]
|
|
168
|
-
properties:
|
|
169
|
-
entity_type:
|
|
170
|
-
type: string
|
|
171
|
-
const: node
|
|
172
|
-
entity_id:
|
|
173
|
-
type: integer
|
|
174
|
-
bundle:
|
|
175
|
-
type: string
|
|
176
|
-
const: article
|
|
177
|
-
field_data:
|
|
178
|
-
type: object
|
|
179
|
-
|
|
180
|
-
integration:
|
|
181
|
-
protocol: http
|
|
182
|
-
endpoints:
|
|
183
|
-
base_url: http://content-handler:3000
|
|
184
|
-
webhook: /api/v1/drupal/presave
|
|
185
|
-
auth:
|
|
186
|
-
type: api_key
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Drupal Integration Code:**
|
|
190
|
-
```php
|
|
191
|
-
/**
|
|
192
|
-
* Implements hook_entity_presave().
|
|
193
|
-
*/
|
|
194
|
-
function mymodule_entity_presave(EntityInterface $entity) {
|
|
195
|
-
if ($entity->getEntityTypeId() === 'node' && $entity->bundle() === 'article') {
|
|
196
|
-
$client = \Drupal::httpClient();
|
|
197
|
-
$response = $client->post('http://content-handler:3000/api/v1/drupal/presave', [
|
|
198
|
-
'json' => [
|
|
199
|
-
'entity_type' => 'node',
|
|
200
|
-
'entity_id' => $entity->id(),
|
|
201
|
-
'bundle' => 'article',
|
|
202
|
-
'field_data' => $entity->toArray(),
|
|
203
|
-
],
|
|
204
|
-
'headers' => [
|
|
205
|
-
'Authorization' => 'Bearer ' . getenv('OSSA_API_KEY'),
|
|
206
|
-
],
|
|
207
|
-
]);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Pattern 2: ECA Conditions → OSSA Schema Validation & Policies
|
|
213
|
-
|
|
214
|
-
**ECA Condition:**
|
|
215
|
-
```yaml
|
|
216
|
-
# ECA Model
|
|
217
|
-
conditions:
|
|
218
|
-
- plugin: entity_field_value_compare
|
|
219
|
-
field: field_status
|
|
220
|
-
operator: equals
|
|
221
|
-
value: published
|
|
222
|
-
- plugin: user_has_role
|
|
223
|
-
role: editor
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**OSSA Agent (Schema + Policy Enforcement):**
|
|
227
|
-
```yaml
|
|
228
|
-
ossaVersion: "0.2.5-RC"
|
|
229
|
-
agent:
|
|
230
|
-
id: content-moderator
|
|
231
|
-
name: Content Moderation Agent
|
|
232
|
-
version: 1.0.0
|
|
233
|
-
|
|
234
|
-
capabilities:
|
|
235
|
-
- name: moderate_content
|
|
236
|
-
description: Moderate content with role-based validation
|
|
237
|
-
input_schema:
|
|
238
|
-
type: object
|
|
239
|
-
required: [field_status, user_roles]
|
|
240
|
-
properties:
|
|
241
|
-
field_status:
|
|
242
|
-
type: string
|
|
243
|
-
enum: [draft, published, archived]
|
|
244
|
-
user_roles:
|
|
245
|
-
type: array
|
|
246
|
-
items:
|
|
247
|
-
type: string
|
|
248
|
-
contains:
|
|
249
|
-
const: editor # Enforces editor role requirement
|
|
250
|
-
content:
|
|
251
|
-
type: object
|
|
252
|
-
output_schema:
|
|
253
|
-
type: object
|
|
254
|
-
properties:
|
|
255
|
-
approved:
|
|
256
|
-
type: boolean
|
|
257
|
-
message:
|
|
258
|
-
type: string
|
|
259
|
-
|
|
260
|
-
policies:
|
|
261
|
-
compliance:
|
|
262
|
-
- content-moderation
|
|
263
|
-
authorization_required: true
|
|
264
|
-
role_validation:
|
|
265
|
-
required_roles: [editor]
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Pattern 3: ECA Actions → OSSA Capabilities
|
|
269
|
-
|
|
270
|
-
**ECA Action:**
|
|
271
|
-
```yaml
|
|
272
|
-
# ECA Model
|
|
273
|
-
actions:
|
|
274
|
-
- plugin: entity:save
|
|
275
|
-
entity: node
|
|
276
|
-
- plugin: eca_tamper:change_case
|
|
277
|
-
field: title
|
|
278
|
-
case: uppercase
|
|
279
|
-
- plugin: eca_email:send
|
|
280
|
-
to: "admin@example.com"
|
|
281
|
-
subject: "Content updated"
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**OSSA Agent (Multi-Capability):**
|
|
285
|
-
```yaml
|
|
286
|
-
ossaVersion: "0.2.5-RC"
|
|
287
|
-
agent:
|
|
288
|
-
id: content-processor
|
|
289
|
-
name: Content Processing Agent
|
|
290
|
-
version: 1.0.0
|
|
291
|
-
role: data_processing
|
|
292
|
-
|
|
293
|
-
capabilities:
|
|
294
|
-
- name: transform_content
|
|
295
|
-
description: Transform content fields
|
|
296
|
-
input_schema:
|
|
297
|
-
type: object
|
|
298
|
-
properties:
|
|
299
|
-
title:
|
|
300
|
-
type: string
|
|
301
|
-
body:
|
|
302
|
-
type: string
|
|
303
|
-
transformations:
|
|
304
|
-
type: array
|
|
305
|
-
items:
|
|
306
|
-
type: object
|
|
307
|
-
properties:
|
|
308
|
-
field:
|
|
309
|
-
type: string
|
|
310
|
-
operation:
|
|
311
|
-
type: string
|
|
312
|
-
enum: [uppercase, lowercase, trim]
|
|
313
|
-
output_schema:
|
|
314
|
-
type: object
|
|
315
|
-
properties:
|
|
316
|
-
transformed_data:
|
|
317
|
-
type: object
|
|
318
|
-
|
|
319
|
-
- name: save_to_drupal
|
|
320
|
-
description: Save content back to Drupal
|
|
321
|
-
input_schema:
|
|
322
|
-
type: object
|
|
323
|
-
required: [entity_type, entity_id, data]
|
|
324
|
-
properties:
|
|
325
|
-
entity_type:
|
|
326
|
-
type: string
|
|
327
|
-
entity_id:
|
|
328
|
-
type: integer
|
|
329
|
-
data:
|
|
330
|
-
type: object
|
|
331
|
-
output_schema:
|
|
332
|
-
type: object
|
|
333
|
-
properties:
|
|
334
|
-
saved:
|
|
335
|
-
type: boolean
|
|
336
|
-
entity_id:
|
|
337
|
-
type: integer
|
|
338
|
-
|
|
339
|
-
- name: send_notification
|
|
340
|
-
description: Send email notification
|
|
341
|
-
input_schema:
|
|
342
|
-
type: object
|
|
343
|
-
required: [to, subject, body]
|
|
344
|
-
properties:
|
|
345
|
-
to:
|
|
346
|
-
type: string
|
|
347
|
-
format: email
|
|
348
|
-
subject:
|
|
349
|
-
type: string
|
|
350
|
-
body:
|
|
351
|
-
type: string
|
|
352
|
-
output_schema:
|
|
353
|
-
type: object
|
|
354
|
-
properties:
|
|
355
|
-
sent:
|
|
356
|
-
type: boolean
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
### Pattern 4: Drupal Hooks → OSSA Runtime Integration
|
|
360
|
-
|
|
361
|
-
**Drupal Hook Integration Module:**
|
|
362
|
-
|
|
363
|
-
```php
|
|
364
|
-
<?php
|
|
365
|
-
/**
|
|
366
|
-
* @file
|
|
367
|
-
* OSSA Integration module for Drupal.
|
|
368
|
-
*/
|
|
369
|
-
|
|
370
|
-
namespace Drupal\ossa_integration;
|
|
371
|
-
|
|
372
|
-
use Drupal\Core\Entity\EntityInterface;
|
|
373
|
-
use GuzzleHttp\ClientInterface;
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Service for OSSA agent communication.
|
|
377
|
-
*/
|
|
378
|
-
class OssaAgentService {
|
|
379
|
-
|
|
380
|
-
protected ClientInterface $httpClient;
|
|
381
|
-
protected string $baseUrl;
|
|
382
|
-
protected string $apiKey;
|
|
383
|
-
|
|
384
|
-
public function __construct(ClientInterface $httpClient) {
|
|
385
|
-
$this->httpClient = $httpClient;
|
|
386
|
-
$this->baseUrl = getenv('OSSA_BASE_URL') ?: 'http://ossa-gateway:8080';
|
|
387
|
-
$this->apiKey = getenv('OSSA_API_KEY');
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Trigger OSSA agent capability.
|
|
392
|
-
*/
|
|
393
|
-
public function triggerCapability(string $agentId, string $capability, array $input): array {
|
|
394
|
-
$url = "{$this->baseUrl}/api/v1/agents/{$agentId}/capabilities/{$capability}";
|
|
395
|
-
|
|
396
|
-
$response = $this->httpClient->post($url, [
|
|
397
|
-
'json' => $input,
|
|
398
|
-
'headers' => [
|
|
399
|
-
'Authorization' => "Bearer {$this->apiKey}",
|
|
400
|
-
'Content-Type' => 'application/json',
|
|
401
|
-
],
|
|
402
|
-
]);
|
|
403
|
-
|
|
404
|
-
return json_decode($response->getBody()->getContents(), TRUE);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Handle entity presave events.
|
|
409
|
-
*/
|
|
410
|
-
public function handleEntityPresave(EntityInterface $entity): void {
|
|
411
|
-
$data = [
|
|
412
|
-
'entity_type' => $entity->getEntityTypeId(),
|
|
413
|
-
'entity_id' => $entity->id(),
|
|
414
|
-
'bundle' => $entity->bundle(),
|
|
415
|
-
'field_data' => $this->serializeEntity($entity),
|
|
416
|
-
'langcode' => $entity->language()->getId(),
|
|
417
|
-
];
|
|
418
|
-
|
|
419
|
-
$this->triggerCapability('drupal-content-handler', 'handle_entity_presave', $data);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Serialize entity for OSSA agents.
|
|
424
|
-
*/
|
|
425
|
-
protected function serializeEntity(EntityInterface $entity): array {
|
|
426
|
-
$data = [];
|
|
427
|
-
foreach ($entity->getFields() as $field_name => $field) {
|
|
428
|
-
$data[$field_name] = $field->getValue();
|
|
429
|
-
}
|
|
430
|
-
return $data;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
**Hook Implementation:**
|
|
436
|
-
|
|
437
|
-
```php
|
|
438
|
-
/**
|
|
439
|
-
* Implements hook_entity_presave().
|
|
440
|
-
*/
|
|
441
|
-
function ossa_integration_entity_presave(EntityInterface $entity) {
|
|
442
|
-
/** @var \Drupal\ossa_integration\OssaAgentService $ossaService */
|
|
443
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
444
|
-
$ossaService->handleEntityPresave($entity);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Implements hook_user_login().
|
|
449
|
-
*/
|
|
450
|
-
function ossa_integration_user_login($account) {
|
|
451
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
452
|
-
$ossaService->triggerCapability('user-activity-tracker', 'track_login', [
|
|
453
|
-
'user_id' => $account->id(),
|
|
454
|
-
'username' => $account->getAccountName(),
|
|
455
|
-
'timestamp' => time(),
|
|
456
|
-
'ip_address' => \Drupal::request()->getClientIp(),
|
|
457
|
-
]);
|
|
458
|
-
}
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### Pattern 5: Content Workflows → OSSA Orchestration
|
|
462
|
-
|
|
463
|
-
**ECA Workflow (Content Moderation):**
|
|
464
|
-
```yaml
|
|
465
|
-
# ECA BPMN Model (simplified)
|
|
466
|
-
workflow:
|
|
467
|
-
start: content_created
|
|
468
|
-
steps:
|
|
469
|
-
- check_content_quality
|
|
470
|
-
- assign_to_editor
|
|
471
|
-
- wait_for_approval
|
|
472
|
-
- publish_content
|
|
473
|
-
- notify_stakeholders
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
**OSSA Orchestrator Agent:**
|
|
477
|
-
```yaml
|
|
478
|
-
ossaVersion: "0.2.5-RC"
|
|
479
|
-
agent:
|
|
480
|
-
id: content-workflow-orchestrator
|
|
481
|
-
name: Content Workflow Orchestrator
|
|
482
|
-
version: 1.0.0
|
|
483
|
-
role: orchestration
|
|
484
|
-
|
|
485
|
-
runtime:
|
|
486
|
-
type: k8s
|
|
487
|
-
resources:
|
|
488
|
-
cpu: '1000m'
|
|
489
|
-
memory: '1Gi'
|
|
490
|
-
|
|
491
|
-
capabilities:
|
|
492
|
-
- name: execute_content_workflow
|
|
493
|
-
description: Execute multi-step content moderation workflow
|
|
494
|
-
input_schema:
|
|
495
|
-
type: object
|
|
496
|
-
required: [content_id, workflow_type]
|
|
497
|
-
properties:
|
|
498
|
-
content_id:
|
|
499
|
-
type: integer
|
|
500
|
-
workflow_type:
|
|
501
|
-
type: string
|
|
502
|
-
enum: [article, page, product]
|
|
503
|
-
initial_data:
|
|
504
|
-
type: object
|
|
505
|
-
output_schema:
|
|
506
|
-
type: object
|
|
507
|
-
properties:
|
|
508
|
-
execution_id:
|
|
509
|
-
type: string
|
|
510
|
-
status:
|
|
511
|
-
type: string
|
|
512
|
-
enum: [queued, running, completed, failed]
|
|
513
|
-
steps_completed:
|
|
514
|
-
type: array
|
|
515
|
-
items:
|
|
516
|
-
type: object
|
|
517
|
-
properties:
|
|
518
|
-
step_name:
|
|
519
|
-
type: string
|
|
520
|
-
status:
|
|
521
|
-
type: string
|
|
522
|
-
result:
|
|
523
|
-
type: object
|
|
524
|
-
timeout_seconds: 3600
|
|
525
|
-
|
|
526
|
-
dependencies:
|
|
527
|
-
required:
|
|
528
|
-
- agent_id: content-quality-checker
|
|
529
|
-
min_version: '1.0.0'
|
|
530
|
-
- agent_id: editor-assignment-agent
|
|
531
|
-
min_version: '1.0.0'
|
|
532
|
-
- agent_id: notification-service
|
|
533
|
-
min_version: '1.0.0'
|
|
534
|
-
optional:
|
|
535
|
-
- agent_id: ai-content-analyzer
|
|
536
|
-
fallback: Skip AI analysis
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
**Workflow Definition (Separate Config):**
|
|
540
|
-
|
|
541
|
-
```yaml
|
|
542
|
-
# content-moderation-workflow.yaml
|
|
543
|
-
workflow:
|
|
544
|
-
name: content_moderation
|
|
545
|
-
version: 1.0.0
|
|
546
|
-
|
|
547
|
-
steps:
|
|
548
|
-
- id: quality_check
|
|
549
|
-
agent_id: content-quality-checker
|
|
550
|
-
capability: analyze_content
|
|
551
|
-
input:
|
|
552
|
-
content: "{{initial_data.body}}"
|
|
553
|
-
criteria: [grammar, readability, seo]
|
|
554
|
-
depends_on: []
|
|
555
|
-
|
|
556
|
-
- id: ai_enhancement
|
|
557
|
-
agent_id: ai-content-analyzer
|
|
558
|
-
capability: suggest_improvements
|
|
559
|
-
input:
|
|
560
|
-
content: "{{steps.quality_check.result.content}}"
|
|
561
|
-
quality_score: "{{steps.quality_check.result.score}}"
|
|
562
|
-
depends_on: [quality_check]
|
|
563
|
-
optional: true
|
|
564
|
-
|
|
565
|
-
- id: assign_editor
|
|
566
|
-
agent_id: editor-assignment-agent
|
|
567
|
-
capability: assign_to_editor
|
|
568
|
-
input:
|
|
569
|
-
content_type: "{{workflow_type}}"
|
|
570
|
-
complexity: "{{steps.quality_check.result.complexity}}"
|
|
571
|
-
depends_on: [quality_check]
|
|
572
|
-
|
|
573
|
-
- id: notify_editor
|
|
574
|
-
agent_id: notification-service
|
|
575
|
-
capability: send_notification
|
|
576
|
-
input:
|
|
577
|
-
recipient: "{{steps.assign_editor.result.editor_email}}"
|
|
578
|
-
template: editor_assignment
|
|
579
|
-
data:
|
|
580
|
-
content_id: "{{content_id}}"
|
|
581
|
-
content_title: "{{initial_data.title}}"
|
|
582
|
-
depends_on: [assign_editor]
|
|
583
|
-
|
|
584
|
-
- id: await_approval
|
|
585
|
-
agent_id: approval-workflow-agent
|
|
586
|
-
capability: wait_for_approval
|
|
587
|
-
input:
|
|
588
|
-
content_id: "{{content_id}}"
|
|
589
|
-
approver: "{{steps.assign_editor.result.editor_id}}"
|
|
590
|
-
timeout_hours: 48
|
|
591
|
-
depends_on: [notify_editor]
|
|
592
|
-
|
|
593
|
-
- id: publish_content
|
|
594
|
-
agent_id: drupal-content-handler
|
|
595
|
-
capability: publish_content
|
|
596
|
-
input:
|
|
597
|
-
content_id: "{{content_id}}"
|
|
598
|
-
approval_data: "{{steps.await_approval.result}}"
|
|
599
|
-
depends_on: [await_approval]
|
|
600
|
-
condition: "{{steps.await_approval.result.approved == true}}"
|
|
601
|
-
|
|
602
|
-
- id: notify_stakeholders
|
|
603
|
-
agent_id: notification-service
|
|
604
|
-
capability: send_bulk_notification
|
|
605
|
-
input:
|
|
606
|
-
recipients: "{{initial_data.stakeholders}}"
|
|
607
|
-
template: content_published
|
|
608
|
-
data:
|
|
609
|
-
content_id: "{{content_id}}"
|
|
610
|
-
url: "{{steps.publish_content.result.url}}"
|
|
611
|
-
depends_on: [publish_content]
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
---
|
|
615
|
-
|
|
616
|
-
## Example Migrations
|
|
617
|
-
|
|
618
|
-
### Example 1: Content Moderation Workflow
|
|
619
|
-
|
|
620
|
-
#### ECA Configuration (Before)
|
|
621
|
-
|
|
622
|
-
```yaml
|
|
623
|
-
# ECA Model: article_moderation.eca.yml
|
|
624
|
-
langcode: en
|
|
625
|
-
status: true
|
|
626
|
-
label: 'Article Moderation Workflow'
|
|
627
|
-
id: article_moderation
|
|
628
|
-
modeller: core
|
|
629
|
-
version: 1.0.0
|
|
630
|
-
|
|
631
|
-
events:
|
|
632
|
-
event_1:
|
|
633
|
-
plugin: 'entity:presave:node:article'
|
|
634
|
-
configuration:
|
|
635
|
-
bundle: article
|
|
636
|
-
|
|
637
|
-
conditions:
|
|
638
|
-
condition_1:
|
|
639
|
-
plugin: entity_field_value_compare
|
|
640
|
-
configuration:
|
|
641
|
-
field: moderation_state
|
|
642
|
-
operator: equals
|
|
643
|
-
value: needs_review
|
|
644
|
-
|
|
645
|
-
condition_2:
|
|
646
|
-
plugin: token_compare
|
|
647
|
-
configuration:
|
|
648
|
-
token: '[node:author:field_experience_level]'
|
|
649
|
-
operator: less_than
|
|
650
|
-
value: 'senior'
|
|
651
|
-
|
|
652
|
-
actions:
|
|
653
|
-
action_1:
|
|
654
|
-
plugin: 'eca_content:flag_for_review'
|
|
655
|
-
configuration:
|
|
656
|
-
reviewer_role: editor
|
|
657
|
-
priority: normal
|
|
658
|
-
|
|
659
|
-
action_2:
|
|
660
|
-
plugin: 'eca_email:send'
|
|
661
|
-
configuration:
|
|
662
|
-
to: '[site:editor-email]'
|
|
663
|
-
subject: 'New article needs review'
|
|
664
|
-
body: 'Article "[node:title]" by [node:author] needs editorial review.'
|
|
665
|
-
|
|
666
|
-
action_3:
|
|
667
|
-
plugin: 'entity:save'
|
|
668
|
-
configuration:
|
|
669
|
-
entity: node
|
|
670
|
-
```
|
|
671
|
-
|
|
672
|
-
#### OSSA Agent (After)
|
|
673
|
-
|
|
674
|
-
```yaml
|
|
675
|
-
# drupal-content-moderator.ossa.yaml
|
|
676
|
-
ossaVersion: "0.2.5-RC"
|
|
677
|
-
|
|
678
|
-
agent:
|
|
679
|
-
id: drupal-content-moderator
|
|
680
|
-
name: Drupal Content Moderation Agent
|
|
681
|
-
version: 1.0.0
|
|
682
|
-
description: |
|
|
683
|
-
Content moderation agent for Drupal articles.
|
|
684
|
-
Handles review assignment, notifications, and workflow state management.
|
|
685
|
-
role: workflow
|
|
686
|
-
tags:
|
|
687
|
-
- drupal
|
|
688
|
-
- content-moderation
|
|
689
|
-
- workflow
|
|
690
|
-
- article-review
|
|
691
|
-
|
|
692
|
-
runtime:
|
|
693
|
-
type: docker
|
|
694
|
-
image: ossa/drupal-moderator:1.0.0
|
|
695
|
-
requirements:
|
|
696
|
-
node: '>=20.0.0'
|
|
697
|
-
packages:
|
|
698
|
-
- '@drupal/node-sdk'
|
|
699
|
-
- nodemailer
|
|
700
|
-
resources:
|
|
701
|
-
cpu: '500m'
|
|
702
|
-
memory: '512Mi'
|
|
703
|
-
health_check:
|
|
704
|
-
type: http
|
|
705
|
-
endpoint: /health
|
|
706
|
-
port: 3200
|
|
707
|
-
|
|
708
|
-
capabilities:
|
|
709
|
-
- name: moderate_article_presave
|
|
710
|
-
description: Process article moderation before save
|
|
711
|
-
input_schema:
|
|
712
|
-
type: object
|
|
713
|
-
required:
|
|
714
|
-
- entity_id
|
|
715
|
-
- moderation_state
|
|
716
|
-
- author_experience_level
|
|
717
|
-
- title
|
|
718
|
-
- author_name
|
|
719
|
-
properties:
|
|
720
|
-
entity_id:
|
|
721
|
-
type: integer
|
|
722
|
-
moderation_state:
|
|
723
|
-
type: string
|
|
724
|
-
enum: [draft, needs_review, published, archived]
|
|
725
|
-
author_experience_level:
|
|
726
|
-
type: string
|
|
727
|
-
enum: [junior, intermediate, senior]
|
|
728
|
-
title:
|
|
729
|
-
type: string
|
|
730
|
-
author_name:
|
|
731
|
-
type: string
|
|
732
|
-
author_email:
|
|
733
|
-
type: string
|
|
734
|
-
format: email
|
|
735
|
-
output_schema:
|
|
736
|
-
type: object
|
|
737
|
-
properties:
|
|
738
|
-
requires_review:
|
|
739
|
-
type: boolean
|
|
740
|
-
assigned_reviewer:
|
|
741
|
-
type: string
|
|
742
|
-
notification_sent:
|
|
743
|
-
type: boolean
|
|
744
|
-
updated_state:
|
|
745
|
-
type: string
|
|
746
|
-
timeout_seconds: 30
|
|
747
|
-
retry_policy:
|
|
748
|
-
max_attempts: 3
|
|
749
|
-
backoff: exponential
|
|
750
|
-
|
|
751
|
-
- name: assign_reviewer
|
|
752
|
-
description: Assign article to appropriate reviewer
|
|
753
|
-
input_schema:
|
|
754
|
-
type: object
|
|
755
|
-
required: [article_id, priority]
|
|
756
|
-
properties:
|
|
757
|
-
article_id:
|
|
758
|
-
type: integer
|
|
759
|
-
priority:
|
|
760
|
-
type: string
|
|
761
|
-
enum: [low, normal, high, urgent]
|
|
762
|
-
required_role:
|
|
763
|
-
type: string
|
|
764
|
-
default: editor
|
|
765
|
-
output_schema:
|
|
766
|
-
type: object
|
|
767
|
-
properties:
|
|
768
|
-
reviewer_id:
|
|
769
|
-
type: integer
|
|
770
|
-
reviewer_email:
|
|
771
|
-
type: string
|
|
772
|
-
assignment_id:
|
|
773
|
-
type: string
|
|
774
|
-
|
|
775
|
-
- name: send_review_notification
|
|
776
|
-
description: Send email notification to reviewer
|
|
777
|
-
input_schema:
|
|
778
|
-
type: object
|
|
779
|
-
required: [recipient, article_title, author_name]
|
|
780
|
-
properties:
|
|
781
|
-
recipient:
|
|
782
|
-
type: string
|
|
783
|
-
format: email
|
|
784
|
-
article_title:
|
|
785
|
-
type: string
|
|
786
|
-
author_name:
|
|
787
|
-
type: string
|
|
788
|
-
article_url:
|
|
789
|
-
type: string
|
|
790
|
-
format: uri
|
|
791
|
-
output_schema:
|
|
792
|
-
type: object
|
|
793
|
-
properties:
|
|
794
|
-
sent:
|
|
795
|
-
type: boolean
|
|
796
|
-
message_id:
|
|
797
|
-
type: string
|
|
798
|
-
|
|
799
|
-
policies:
|
|
800
|
-
compliance:
|
|
801
|
-
- content-moderation-policy
|
|
802
|
-
data_residency: [US]
|
|
803
|
-
encryption: true
|
|
804
|
-
audit: true
|
|
805
|
-
pii_handling: encrypt
|
|
806
|
-
|
|
807
|
-
integration:
|
|
808
|
-
protocol: http
|
|
809
|
-
endpoints:
|
|
810
|
-
base_url: http://drupal-moderator:3200
|
|
811
|
-
health: /health
|
|
812
|
-
metrics: /metrics
|
|
813
|
-
webhook: /api/v1/drupal/moderate
|
|
814
|
-
auth:
|
|
815
|
-
type: api_key
|
|
816
|
-
config:
|
|
817
|
-
header: X-API-Key
|
|
818
|
-
rate_limits:
|
|
819
|
-
requests_per_second: 50
|
|
820
|
-
burst: 20
|
|
821
|
-
|
|
822
|
-
monitoring:
|
|
823
|
-
traces: true
|
|
824
|
-
metrics: true
|
|
825
|
-
logs: true
|
|
826
|
-
health_check: http://localhost:3200/health
|
|
827
|
-
phoenix_arise:
|
|
828
|
-
enabled: true
|
|
829
|
-
project: drupal-moderation
|
|
830
|
-
export_interval_seconds: 30
|
|
831
|
-
|
|
832
|
-
dependencies:
|
|
833
|
-
required:
|
|
834
|
-
- agent_id: notification-service
|
|
835
|
-
min_version: '1.0.0'
|
|
836
|
-
optional:
|
|
837
|
-
- agent_id: ai-content-analyzer
|
|
838
|
-
fallback: Skip AI analysis
|
|
839
|
-
|
|
840
|
-
metadata:
|
|
841
|
-
author: LLM Platform Team
|
|
842
|
-
maintainer: team@example.com
|
|
843
|
-
license: Apache-2.0
|
|
844
|
-
documentation: https://docs.example.com/agents/drupal-moderator
|
|
845
|
-
keywords:
|
|
846
|
-
- drupal
|
|
847
|
-
- moderation
|
|
848
|
-
- content
|
|
849
|
-
- workflow
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
**Drupal Integration:**
|
|
853
|
-
|
|
854
|
-
```php
|
|
855
|
-
<?php
|
|
856
|
-
/**
|
|
857
|
-
* Implements hook_entity_presave().
|
|
858
|
-
*/
|
|
859
|
-
function ossa_drupal_entity_presave(EntityInterface $entity) {
|
|
860
|
-
if ($entity->getEntityTypeId() !== 'node' || $entity->bundle() !== 'article') {
|
|
861
|
-
return;
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
/** @var \Drupal\ossa_integration\OssaAgentService $ossaService */
|
|
865
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
866
|
-
|
|
867
|
-
$author = $entity->getOwner();
|
|
868
|
-
$experience_level = $author->get('field_experience_level')->value ?? 'junior';
|
|
869
|
-
|
|
870
|
-
$result = $ossaService->triggerCapability(
|
|
871
|
-
'drupal-content-moderator',
|
|
872
|
-
'moderate_article_presave',
|
|
873
|
-
[
|
|
874
|
-
'entity_id' => $entity->id(),
|
|
875
|
-
'moderation_state' => $entity->get('moderation_state')->value,
|
|
876
|
-
'author_experience_level' => $experience_level,
|
|
877
|
-
'title' => $entity->getTitle(),
|
|
878
|
-
'author_name' => $author->getDisplayName(),
|
|
879
|
-
'author_email' => $author->getEmail(),
|
|
880
|
-
]
|
|
881
|
-
);
|
|
882
|
-
|
|
883
|
-
// Update entity based on agent response
|
|
884
|
-
if ($result['requires_review']) {
|
|
885
|
-
$entity->set('moderation_state', $result['updated_state']);
|
|
886
|
-
\Drupal::logger('ossa_drupal')->info(
|
|
887
|
-
'Article @id assigned to reviewer @reviewer',
|
|
888
|
-
[
|
|
889
|
-
'@id' => $entity->id(),
|
|
890
|
-
'@reviewer' => $result['assigned_reviewer'],
|
|
891
|
-
]
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
```
|
|
896
|
-
|
|
897
|
-
---
|
|
898
|
-
|
|
899
|
-
### Example 2: User Workflow (Registration & Onboarding)
|
|
900
|
-
|
|
901
|
-
#### ECA Configuration (Before)
|
|
902
|
-
|
|
903
|
-
```yaml
|
|
904
|
-
# ECA Model: user_onboarding.eca.yml
|
|
905
|
-
langcode: en
|
|
906
|
-
status: true
|
|
907
|
-
label: 'User Registration and Onboarding'
|
|
908
|
-
id: user_onboarding
|
|
909
|
-
modeller: core
|
|
910
|
-
version: 1.0.0
|
|
911
|
-
|
|
912
|
-
events:
|
|
913
|
-
event_1:
|
|
914
|
-
plugin: 'user:insert'
|
|
915
|
-
|
|
916
|
-
conditions:
|
|
917
|
-
condition_1:
|
|
918
|
-
plugin: user_role_compare
|
|
919
|
-
configuration:
|
|
920
|
-
role: authenticated
|
|
921
|
-
|
|
922
|
-
condition_2:
|
|
923
|
-
plugin: token_compare
|
|
924
|
-
configuration:
|
|
925
|
-
token: '[user:field_account_type]'
|
|
926
|
-
operator: equals
|
|
927
|
-
value: 'premium'
|
|
928
|
-
|
|
929
|
-
actions:
|
|
930
|
-
action_1:
|
|
931
|
-
plugin: 'eca_user:create_welcome_message'
|
|
932
|
-
configuration:
|
|
933
|
-
message_type: welcome
|
|
934
|
-
|
|
935
|
-
action_2:
|
|
936
|
-
plugin: 'eca_email:send'
|
|
937
|
-
configuration:
|
|
938
|
-
to: '[user:mail]'
|
|
939
|
-
subject: 'Welcome to [site:name]'
|
|
940
|
-
body: 'Template: welcome_premium_user'
|
|
941
|
-
|
|
942
|
-
action_3:
|
|
943
|
-
plugin: 'eca_content:create_node'
|
|
944
|
-
configuration:
|
|
945
|
-
type: onboarding_task
|
|
946
|
-
title: 'Complete your profile'
|
|
947
|
-
owner: '[user:uid]'
|
|
948
|
-
|
|
949
|
-
action_4:
|
|
950
|
-
plugin: 'eca_user:assign_to_group'
|
|
951
|
-
configuration:
|
|
952
|
-
group: premium_members
|
|
953
|
-
|
|
954
|
-
action_5:
|
|
955
|
-
plugin: 'eca_state:set_value'
|
|
956
|
-
configuration:
|
|
957
|
-
key: 'onboarding_started_[user:uid]'
|
|
958
|
-
value: '[current-date:timestamp]'
|
|
959
|
-
```
|
|
960
|
-
|
|
961
|
-
#### OSSA Agent (After)
|
|
962
|
-
|
|
963
|
-
```yaml
|
|
964
|
-
# user-onboarding-agent.ossa.yaml
|
|
965
|
-
ossaVersion: "0.2.5-RC"
|
|
966
|
-
|
|
967
|
-
agent:
|
|
968
|
-
id: user-onboarding-orchestrator
|
|
969
|
-
name: User Onboarding Orchestration Agent
|
|
970
|
-
version: 1.0.0
|
|
971
|
-
description: |
|
|
972
|
-
Manages user registration workflows, onboarding tasks,
|
|
973
|
-
welcome messaging, and account setup automation.
|
|
974
|
-
role: workflow
|
|
975
|
-
tags:
|
|
976
|
-
- user-management
|
|
977
|
-
- onboarding
|
|
978
|
-
- registration
|
|
979
|
-
- drupal
|
|
980
|
-
|
|
981
|
-
runtime:
|
|
982
|
-
type: docker
|
|
983
|
-
image: ossa/user-onboarding:1.0.0
|
|
984
|
-
requirements:
|
|
985
|
-
node: '>=20.0.0'
|
|
986
|
-
packages:
|
|
987
|
-
- '@drupal/user-api'
|
|
988
|
-
- bull
|
|
989
|
-
- ioredis
|
|
990
|
-
resources:
|
|
991
|
-
cpu: '500m'
|
|
992
|
-
memory: '768Mi'
|
|
993
|
-
|
|
994
|
-
capabilities:
|
|
995
|
-
- name: handle_user_registration
|
|
996
|
-
description: Orchestrate user registration and onboarding workflow
|
|
997
|
-
input_schema:
|
|
998
|
-
type: object
|
|
999
|
-
required: [user_id, email, account_type, username]
|
|
1000
|
-
properties:
|
|
1001
|
-
user_id:
|
|
1002
|
-
type: integer
|
|
1003
|
-
email:
|
|
1004
|
-
type: string
|
|
1005
|
-
format: email
|
|
1006
|
-
username:
|
|
1007
|
-
type: string
|
|
1008
|
-
account_type:
|
|
1009
|
-
type: string
|
|
1010
|
-
enum: [free, premium, enterprise]
|
|
1011
|
-
roles:
|
|
1012
|
-
type: array
|
|
1013
|
-
items:
|
|
1014
|
-
type: string
|
|
1015
|
-
profile_data:
|
|
1016
|
-
type: object
|
|
1017
|
-
output_schema:
|
|
1018
|
-
type: object
|
|
1019
|
-
properties:
|
|
1020
|
-
onboarding_id:
|
|
1021
|
-
type: string
|
|
1022
|
-
tasks_created:
|
|
1023
|
-
type: array
|
|
1024
|
-
items:
|
|
1025
|
-
type: object
|
|
1026
|
-
welcome_sent:
|
|
1027
|
-
type: boolean
|
|
1028
|
-
group_assigned:
|
|
1029
|
-
type: boolean
|
|
1030
|
-
timeout_seconds: 120
|
|
1031
|
-
|
|
1032
|
-
- name: create_welcome_message
|
|
1033
|
-
description: Create personalized welcome message
|
|
1034
|
-
input_schema:
|
|
1035
|
-
type: object
|
|
1036
|
-
required: [user_id, message_type, account_type]
|
|
1037
|
-
properties:
|
|
1038
|
-
user_id:
|
|
1039
|
-
type: integer
|
|
1040
|
-
message_type:
|
|
1041
|
-
type: string
|
|
1042
|
-
enum: [welcome, tutorial, premium_features]
|
|
1043
|
-
account_type:
|
|
1044
|
-
type: string
|
|
1045
|
-
output_schema:
|
|
1046
|
-
type: object
|
|
1047
|
-
properties:
|
|
1048
|
-
message_id:
|
|
1049
|
-
type: string
|
|
1050
|
-
content:
|
|
1051
|
-
type: string
|
|
1052
|
-
|
|
1053
|
-
- name: create_onboarding_tasks
|
|
1054
|
-
description: Create personalized onboarding tasks
|
|
1055
|
-
input_schema:
|
|
1056
|
-
type: object
|
|
1057
|
-
required: [user_id, account_type]
|
|
1058
|
-
properties:
|
|
1059
|
-
user_id:
|
|
1060
|
-
type: integer
|
|
1061
|
-
account_type:
|
|
1062
|
-
type: string
|
|
1063
|
-
custom_tasks:
|
|
1064
|
-
type: array
|
|
1065
|
-
items:
|
|
1066
|
-
type: object
|
|
1067
|
-
output_schema:
|
|
1068
|
-
type: object
|
|
1069
|
-
properties:
|
|
1070
|
-
tasks:
|
|
1071
|
-
type: array
|
|
1072
|
-
items:
|
|
1073
|
-
type: object
|
|
1074
|
-
properties:
|
|
1075
|
-
task_id:
|
|
1076
|
-
type: string
|
|
1077
|
-
title:
|
|
1078
|
-
type: string
|
|
1079
|
-
status:
|
|
1080
|
-
type: string
|
|
1081
|
-
|
|
1082
|
-
- name: assign_to_group
|
|
1083
|
-
description: Assign user to appropriate groups
|
|
1084
|
-
input_schema:
|
|
1085
|
-
type: object
|
|
1086
|
-
required: [user_id, account_type]
|
|
1087
|
-
properties:
|
|
1088
|
-
user_id:
|
|
1089
|
-
type: integer
|
|
1090
|
-
account_type:
|
|
1091
|
-
type: string
|
|
1092
|
-
custom_groups:
|
|
1093
|
-
type: array
|
|
1094
|
-
items:
|
|
1095
|
-
type: string
|
|
1096
|
-
output_schema:
|
|
1097
|
-
type: object
|
|
1098
|
-
properties:
|
|
1099
|
-
groups_assigned:
|
|
1100
|
-
type: array
|
|
1101
|
-
items:
|
|
1102
|
-
type: string
|
|
1103
|
-
|
|
1104
|
-
policies:
|
|
1105
|
-
compliance:
|
|
1106
|
-
- gdpr
|
|
1107
|
-
- ccpa
|
|
1108
|
-
data_residency: [US, EU]
|
|
1109
|
-
encryption: true
|
|
1110
|
-
audit: true
|
|
1111
|
-
pii_handling: encrypt
|
|
1112
|
-
|
|
1113
|
-
integration:
|
|
1114
|
-
protocol: http
|
|
1115
|
-
endpoints:
|
|
1116
|
-
base_url: http://user-onboarding:3300
|
|
1117
|
-
health: /health
|
|
1118
|
-
webhook: /api/v1/users/register
|
|
1119
|
-
auth:
|
|
1120
|
-
type: jwt
|
|
1121
|
-
config:
|
|
1122
|
-
issuer: https://auth.example.com
|
|
1123
|
-
audience: user-onboarding
|
|
1124
|
-
|
|
1125
|
-
monitoring:
|
|
1126
|
-
traces: true
|
|
1127
|
-
metrics: true
|
|
1128
|
-
logs: true
|
|
1129
|
-
health_check: http://localhost:3300/health
|
|
1130
|
-
|
|
1131
|
-
dependencies:
|
|
1132
|
-
required:
|
|
1133
|
-
- agent_id: notification-service
|
|
1134
|
-
min_version: '1.0.0'
|
|
1135
|
-
- agent_id: drupal-content-handler
|
|
1136
|
-
min_version: '1.0.0'
|
|
1137
|
-
|
|
1138
|
-
metadata:
|
|
1139
|
-
author: LLM Platform Team
|
|
1140
|
-
license: Apache-2.0
|
|
1141
|
-
```
|
|
1142
|
-
|
|
1143
|
-
**Drupal Integration:**
|
|
1144
|
-
|
|
1145
|
-
```php
|
|
1146
|
-
<?php
|
|
1147
|
-
/**
|
|
1148
|
-
* Implements hook_user_insert().
|
|
1149
|
-
*/
|
|
1150
|
-
function ossa_drupal_user_insert(UserInterface $account) {
|
|
1151
|
-
/** @var \Drupal\ossa_integration\OssaAgentService $ossaService */
|
|
1152
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
1153
|
-
|
|
1154
|
-
$account_type = $account->get('field_account_type')->value ?? 'free';
|
|
1155
|
-
|
|
1156
|
-
// Only trigger for premium accounts (condition mapping)
|
|
1157
|
-
if ($account_type !== 'premium') {
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
$result = $ossaService->triggerCapability(
|
|
1162
|
-
'user-onboarding-orchestrator',
|
|
1163
|
-
'handle_user_registration',
|
|
1164
|
-
[
|
|
1165
|
-
'user_id' => $account->id(),
|
|
1166
|
-
'email' => $account->getEmail(),
|
|
1167
|
-
'username' => $account->getAccountName(),
|
|
1168
|
-
'account_type' => $account_type,
|
|
1169
|
-
'roles' => array_values($account->getRoles()),
|
|
1170
|
-
'profile_data' => [
|
|
1171
|
-
'created' => $account->getCreatedTime(),
|
|
1172
|
-
'timezone' => $account->getTimeZone(),
|
|
1173
|
-
],
|
|
1174
|
-
]
|
|
1175
|
-
);
|
|
1176
|
-
|
|
1177
|
-
// Store onboarding state
|
|
1178
|
-
\Drupal::state()->set(
|
|
1179
|
-
"onboarding_started_{$account->id()}",
|
|
1180
|
-
[
|
|
1181
|
-
'onboarding_id' => $result['onboarding_id'],
|
|
1182
|
-
'timestamp' => time(),
|
|
1183
|
-
]
|
|
1184
|
-
);
|
|
1185
|
-
|
|
1186
|
-
\Drupal::logger('ossa_drupal')->info(
|
|
1187
|
-
'User @username onboarding started: @id',
|
|
1188
|
-
[
|
|
1189
|
-
'@username' => $account->getAccountName(),
|
|
1190
|
-
'@id' => $result['onboarding_id'],
|
|
1191
|
-
]
|
|
1192
|
-
);
|
|
1193
|
-
}
|
|
1194
|
-
```
|
|
1195
|
-
|
|
1196
|
-
---
|
|
1197
|
-
|
|
1198
|
-
### Example 3: Data Processing (Commerce Order)
|
|
1199
|
-
|
|
1200
|
-
#### ECA Configuration (Before)
|
|
1201
|
-
|
|
1202
|
-
```yaml
|
|
1203
|
-
# ECA Model: order_processing.eca.yml
|
|
1204
|
-
langcode: en
|
|
1205
|
-
status: true
|
|
1206
|
-
label: 'Commerce Order Processing'
|
|
1207
|
-
id: order_processing
|
|
1208
|
-
modeller: core
|
|
1209
|
-
version: 1.0.0
|
|
1210
|
-
|
|
1211
|
-
events:
|
|
1212
|
-
event_1:
|
|
1213
|
-
plugin: 'commerce_order:paid'
|
|
1214
|
-
|
|
1215
|
-
conditions:
|
|
1216
|
-
condition_1:
|
|
1217
|
-
plugin: commerce_order_total_compare
|
|
1218
|
-
configuration:
|
|
1219
|
-
operator: greater_than
|
|
1220
|
-
value: 1000
|
|
1221
|
-
|
|
1222
|
-
condition_2:
|
|
1223
|
-
plugin: commerce_order_contains_product_type
|
|
1224
|
-
configuration:
|
|
1225
|
-
product_type: subscription
|
|
1226
|
-
|
|
1227
|
-
actions:
|
|
1228
|
-
action_1:
|
|
1229
|
-
plugin: 'eca_commerce:update_order_status'
|
|
1230
|
-
configuration:
|
|
1231
|
-
status: processing
|
|
1232
|
-
|
|
1233
|
-
action_2:
|
|
1234
|
-
plugin: 'eca_commerce:create_fulfillment_record'
|
|
1235
|
-
configuration:
|
|
1236
|
-
warehouse: primary
|
|
1237
|
-
priority: high
|
|
1238
|
-
|
|
1239
|
-
action_3:
|
|
1240
|
-
plugin: 'eca_tamper:transform_data'
|
|
1241
|
-
configuration:
|
|
1242
|
-
source: order_items
|
|
1243
|
-
transformations:
|
|
1244
|
-
- extract_product_ids
|
|
1245
|
-
- calculate_shipping_weight
|
|
1246
|
-
- determine_warehouse_location
|
|
1247
|
-
|
|
1248
|
-
action_4:
|
|
1249
|
-
plugin: 'eca_http:post_request'
|
|
1250
|
-
configuration:
|
|
1251
|
-
url: 'https://warehouse-api.example.com/fulfillment'
|
|
1252
|
-
method: POST
|
|
1253
|
-
body: '[transformed_data]'
|
|
1254
|
-
headers:
|
|
1255
|
-
Authorization: 'Bearer [warehouse_api_token]'
|
|
1256
|
-
|
|
1257
|
-
action_5:
|
|
1258
|
-
plugin: 'eca_email:send'
|
|
1259
|
-
configuration:
|
|
1260
|
-
to: '[order:email]'
|
|
1261
|
-
subject: 'Order Confirmation - High Value Subscription'
|
|
1262
|
-
body: 'Template: order_confirmation_premium'
|
|
1263
|
-
|
|
1264
|
-
action_6:
|
|
1265
|
-
plugin: 'eca_state:set_value'
|
|
1266
|
-
configuration:
|
|
1267
|
-
key: 'order_processed_[order:id]'
|
|
1268
|
-
value: '[current-date:timestamp]'
|
|
1269
|
-
```
|
|
1270
|
-
|
|
1271
|
-
#### OSSA Agent (After)
|
|
1272
|
-
|
|
1273
|
-
```yaml
|
|
1274
|
-
# commerce-order-processor.ossa.yaml
|
|
1275
|
-
ossaVersion: "0.2.5-RC"
|
|
1276
|
-
|
|
1277
|
-
agent:
|
|
1278
|
-
id: commerce-order-processor
|
|
1279
|
-
name: Commerce Order Processing Agent
|
|
1280
|
-
version: 1.0.0
|
|
1281
|
-
description: |
|
|
1282
|
-
Processes high-value commerce orders, handles fulfillment orchestration,
|
|
1283
|
-
data transformation, warehouse integration, and customer notifications.
|
|
1284
|
-
role: data_processing
|
|
1285
|
-
tags:
|
|
1286
|
-
- commerce
|
|
1287
|
-
- order-processing
|
|
1288
|
-
- fulfillment
|
|
1289
|
-
- etl
|
|
1290
|
-
|
|
1291
|
-
runtime:
|
|
1292
|
-
type: k8s
|
|
1293
|
-
image: ossa/order-processor:1.0.0
|
|
1294
|
-
requirements:
|
|
1295
|
-
node: '>=20.0.0'
|
|
1296
|
-
packages:
|
|
1297
|
-
- bull
|
|
1298
|
-
- axios
|
|
1299
|
-
- lodash
|
|
1300
|
-
resources:
|
|
1301
|
-
cpu: '1000m'
|
|
1302
|
-
memory: '2Gi'
|
|
1303
|
-
health_check:
|
|
1304
|
-
type: http
|
|
1305
|
-
endpoint: /health
|
|
1306
|
-
port: 3400
|
|
1307
|
-
|
|
1308
|
-
capabilities:
|
|
1309
|
-
- name: process_paid_order
|
|
1310
|
-
description: Main order processing workflow
|
|
1311
|
-
input_schema:
|
|
1312
|
-
type: object
|
|
1313
|
-
required: [order_id, total_price, order_items, customer_email]
|
|
1314
|
-
properties:
|
|
1315
|
-
order_id:
|
|
1316
|
-
type: integer
|
|
1317
|
-
total_price:
|
|
1318
|
-
type: number
|
|
1319
|
-
minimum: 0
|
|
1320
|
-
order_items:
|
|
1321
|
-
type: array
|
|
1322
|
-
items:
|
|
1323
|
-
type: object
|
|
1324
|
-
properties:
|
|
1325
|
-
product_id:
|
|
1326
|
-
type: integer
|
|
1327
|
-
product_type:
|
|
1328
|
-
type: string
|
|
1329
|
-
quantity:
|
|
1330
|
-
type: integer
|
|
1331
|
-
weight:
|
|
1332
|
-
type: number
|
|
1333
|
-
customer_email:
|
|
1334
|
-
type: string
|
|
1335
|
-
format: email
|
|
1336
|
-
shipping_address:
|
|
1337
|
-
type: object
|
|
1338
|
-
output_schema:
|
|
1339
|
-
type: object
|
|
1340
|
-
properties:
|
|
1341
|
-
processing_id:
|
|
1342
|
-
type: string
|
|
1343
|
-
fulfillment_id:
|
|
1344
|
-
type: string
|
|
1345
|
-
warehouse_assigned:
|
|
1346
|
-
type: string
|
|
1347
|
-
notification_sent:
|
|
1348
|
-
type: boolean
|
|
1349
|
-
status:
|
|
1350
|
-
type: string
|
|
1351
|
-
timeout_seconds: 300
|
|
1352
|
-
retry_policy:
|
|
1353
|
-
max_attempts: 5
|
|
1354
|
-
backoff: exponential
|
|
1355
|
-
|
|
1356
|
-
- name: transform_order_data
|
|
1357
|
-
description: Transform order data for warehouse system
|
|
1358
|
-
input_schema:
|
|
1359
|
-
type: object
|
|
1360
|
-
required: [order_items, shipping_address]
|
|
1361
|
-
properties:
|
|
1362
|
-
order_items:
|
|
1363
|
-
type: array
|
|
1364
|
-
shipping_address:
|
|
1365
|
-
type: object
|
|
1366
|
-
output_schema:
|
|
1367
|
-
type: object
|
|
1368
|
-
properties:
|
|
1369
|
-
product_ids:
|
|
1370
|
-
type: array
|
|
1371
|
-
items:
|
|
1372
|
-
type: integer
|
|
1373
|
-
total_weight:
|
|
1374
|
-
type: number
|
|
1375
|
-
warehouse_location:
|
|
1376
|
-
type: string
|
|
1377
|
-
shipping_method:
|
|
1378
|
-
type: string
|
|
1379
|
-
timeout_seconds: 30
|
|
1380
|
-
|
|
1381
|
-
- name: create_fulfillment_record
|
|
1382
|
-
description: Create fulfillment record in Drupal
|
|
1383
|
-
input_schema:
|
|
1384
|
-
type: object
|
|
1385
|
-
required: [order_id, warehouse, priority]
|
|
1386
|
-
properties:
|
|
1387
|
-
order_id:
|
|
1388
|
-
type: integer
|
|
1389
|
-
warehouse:
|
|
1390
|
-
type: string
|
|
1391
|
-
enum: [primary, secondary, regional]
|
|
1392
|
-
priority:
|
|
1393
|
-
type: string
|
|
1394
|
-
enum: [low, normal, high, urgent]
|
|
1395
|
-
output_schema:
|
|
1396
|
-
type: object
|
|
1397
|
-
properties:
|
|
1398
|
-
fulfillment_id:
|
|
1399
|
-
type: string
|
|
1400
|
-
estimated_ship_date:
|
|
1401
|
-
type: string
|
|
1402
|
-
format: date
|
|
1403
|
-
|
|
1404
|
-
- name: submit_to_warehouse
|
|
1405
|
-
description: Submit fulfillment request to warehouse API
|
|
1406
|
-
input_schema:
|
|
1407
|
-
type: object
|
|
1408
|
-
required: [fulfillment_data, warehouse_endpoint]
|
|
1409
|
-
properties:
|
|
1410
|
-
fulfillment_data:
|
|
1411
|
-
type: object
|
|
1412
|
-
warehouse_endpoint:
|
|
1413
|
-
type: string
|
|
1414
|
-
format: uri
|
|
1415
|
-
api_token:
|
|
1416
|
-
type: string
|
|
1417
|
-
output_schema:
|
|
1418
|
-
type: object
|
|
1419
|
-
properties:
|
|
1420
|
-
warehouse_order_id:
|
|
1421
|
-
type: string
|
|
1422
|
-
status:
|
|
1423
|
-
type: string
|
|
1424
|
-
tracking_available:
|
|
1425
|
-
type: boolean
|
|
1426
|
-
timeout_seconds: 60
|
|
1427
|
-
|
|
1428
|
-
- name: send_order_confirmation
|
|
1429
|
-
description: Send order confirmation email
|
|
1430
|
-
input_schema:
|
|
1431
|
-
type: object
|
|
1432
|
-
required: [customer_email, order_id, order_type]
|
|
1433
|
-
properties:
|
|
1434
|
-
customer_email:
|
|
1435
|
-
type: string
|
|
1436
|
-
format: email
|
|
1437
|
-
order_id:
|
|
1438
|
-
type: integer
|
|
1439
|
-
order_type:
|
|
1440
|
-
type: string
|
|
1441
|
-
enum: [standard, premium, subscription]
|
|
1442
|
-
order_details:
|
|
1443
|
-
type: object
|
|
1444
|
-
output_schema:
|
|
1445
|
-
type: object
|
|
1446
|
-
properties:
|
|
1447
|
-
sent:
|
|
1448
|
-
type: boolean
|
|
1449
|
-
message_id:
|
|
1450
|
-
type: string
|
|
1451
|
-
|
|
1452
|
-
policies:
|
|
1453
|
-
compliance:
|
|
1454
|
-
- pci-dss
|
|
1455
|
-
- soc2-type2
|
|
1456
|
-
data_residency: [US]
|
|
1457
|
-
encryption: true
|
|
1458
|
-
audit: true
|
|
1459
|
-
pii_handling: encrypt
|
|
1460
|
-
|
|
1461
|
-
integration:
|
|
1462
|
-
protocol: http
|
|
1463
|
-
endpoints:
|
|
1464
|
-
base_url: http://order-processor:3400
|
|
1465
|
-
health: /health
|
|
1466
|
-
metrics: /metrics
|
|
1467
|
-
webhook: /api/v1/orders/paid
|
|
1468
|
-
auth:
|
|
1469
|
-
type: api_key
|
|
1470
|
-
rate_limits:
|
|
1471
|
-
requests_per_second: 100
|
|
1472
|
-
burst: 50
|
|
1473
|
-
|
|
1474
|
-
monitoring:
|
|
1475
|
-
traces: true
|
|
1476
|
-
metrics: true
|
|
1477
|
-
logs: true
|
|
1478
|
-
health_check: http://localhost:3400/health
|
|
1479
|
-
phoenix_arise:
|
|
1480
|
-
enabled: true
|
|
1481
|
-
project: commerce-orders
|
|
1482
|
-
export_interval_seconds: 30
|
|
1483
|
-
|
|
1484
|
-
dependencies:
|
|
1485
|
-
required:
|
|
1486
|
-
- agent_id: notification-service
|
|
1487
|
-
min_version: '1.0.0'
|
|
1488
|
-
- agent_id: drupal-content-handler
|
|
1489
|
-
min_version: '1.0.0'
|
|
1490
|
-
optional:
|
|
1491
|
-
- agent_id: analytics-tracker
|
|
1492
|
-
fallback: Skip analytics
|
|
1493
|
-
|
|
1494
|
-
metadata:
|
|
1495
|
-
author: LLM Platform Team
|
|
1496
|
-
license: Apache-2.0
|
|
1497
|
-
```
|
|
1498
|
-
|
|
1499
|
-
**Drupal Integration:**
|
|
1500
|
-
|
|
1501
|
-
```php
|
|
1502
|
-
<?php
|
|
1503
|
-
/**
|
|
1504
|
-
* Implements hook_commerce_order_paid().
|
|
1505
|
-
*/
|
|
1506
|
-
function ossa_drupal_commerce_order_paid(OrderInterface $order) {
|
|
1507
|
-
/** @var \Drupal\ossa_integration\OssaAgentService $ossaService */
|
|
1508
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
1509
|
-
|
|
1510
|
-
$total = $order->getTotalPrice();
|
|
1511
|
-
$order_items = [];
|
|
1512
|
-
|
|
1513
|
-
foreach ($order->getItems() as $item) {
|
|
1514
|
-
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $variation */
|
|
1515
|
-
$variation = $item->getPurchasedEntity();
|
|
1516
|
-
|
|
1517
|
-
$order_items[] = [
|
|
1518
|
-
'product_id' => $variation->getProductId(),
|
|
1519
|
-
'product_type' => $variation->bundle(),
|
|
1520
|
-
'quantity' => (int) $item->getQuantity(),
|
|
1521
|
-
'weight' => $variation->hasField('field_weight')
|
|
1522
|
-
? (float) $variation->get('field_weight')->value
|
|
1523
|
-
: 0,
|
|
1524
|
-
];
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
// Condition: Only process orders > $1000 with subscription products
|
|
1528
|
-
$has_subscription = FALSE;
|
|
1529
|
-
foreach ($order_items as $item) {
|
|
1530
|
-
if ($item['product_type'] === 'subscription') {
|
|
1531
|
-
$has_subscription = TRUE;
|
|
1532
|
-
break;
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
1535
|
-
|
|
1536
|
-
if ($total->getNumber() <= 1000 || !$has_subscription) {
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
$shipping_profile = $order->get('shipments')->entity->getShippingProfile();
|
|
1541
|
-
$address = $shipping_profile->get('address')->first();
|
|
1542
|
-
|
|
1543
|
-
$result = $ossaService->triggerCapability(
|
|
1544
|
-
'commerce-order-processor',
|
|
1545
|
-
'process_paid_order',
|
|
1546
|
-
[
|
|
1547
|
-
'order_id' => $order->id(),
|
|
1548
|
-
'total_price' => (float) $total->getNumber(),
|
|
1549
|
-
'order_items' => $order_items,
|
|
1550
|
-
'customer_email' => $order->getEmail(),
|
|
1551
|
-
'shipping_address' => [
|
|
1552
|
-
'country_code' => $address->getCountryCode(),
|
|
1553
|
-
'postal_code' => $address->getPostalCode(),
|
|
1554
|
-
'locality' => $address->getLocality(),
|
|
1555
|
-
'address_line1' => $address->getAddressLine1(),
|
|
1556
|
-
],
|
|
1557
|
-
]
|
|
1558
|
-
);
|
|
1559
|
-
|
|
1560
|
-
// Update order with processing info
|
|
1561
|
-
$order->setData('ossa_processing_id', $result['processing_id']);
|
|
1562
|
-
$order->setData('ossa_fulfillment_id', $result['fulfillment_id']);
|
|
1563
|
-
$order->save();
|
|
1564
|
-
|
|
1565
|
-
// Store processing state
|
|
1566
|
-
\Drupal::state()->set(
|
|
1567
|
-
"order_processed_{$order->id()}",
|
|
1568
|
-
[
|
|
1569
|
-
'processing_id' => $result['processing_id'],
|
|
1570
|
-
'timestamp' => time(),
|
|
1571
|
-
'warehouse' => $result['warehouse_assigned'],
|
|
1572
|
-
]
|
|
1573
|
-
);
|
|
1574
|
-
|
|
1575
|
-
\Drupal::logger('ossa_drupal')->info(
|
|
1576
|
-
'Order @id processed by OSSA: @processing_id',
|
|
1577
|
-
[
|
|
1578
|
-
'@id' => $order->id(),
|
|
1579
|
-
'@processing_id' => $result['processing_id'],
|
|
1580
|
-
]
|
|
1581
|
-
);
|
|
1582
|
-
}
|
|
1583
|
-
```
|
|
1584
|
-
|
|
1585
|
-
---
|
|
1586
|
-
|
|
1587
|
-
## Integration Strategies
|
|
1588
|
-
|
|
1589
|
-
### Strategy 1: Parallel Operation (Gradual Migration)
|
|
1590
|
-
|
|
1591
|
-
Run ECA and OSSA agents side-by-side during migration:
|
|
1592
|
-
|
|
1593
|
-
```php
|
|
1594
|
-
/**
|
|
1595
|
-
* Parallel operation - ECA and OSSA both active.
|
|
1596
|
-
*/
|
|
1597
|
-
function mymodule_entity_presave(EntityInterface $entity) {
|
|
1598
|
-
// Existing ECA continues to work
|
|
1599
|
-
// OSSA agent also processes in parallel
|
|
1600
|
-
|
|
1601
|
-
if (\Drupal::config('ossa_integration.settings')->get('parallel_mode')) {
|
|
1602
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
1603
|
-
try {
|
|
1604
|
-
$ossaService->handleEntityPresave($entity);
|
|
1605
|
-
} catch (\Exception $e) {
|
|
1606
|
-
\Drupal::logger('ossa_integration')->error(
|
|
1607
|
-
'OSSA agent error: @message',
|
|
1608
|
-
['@message' => $e->getMessage()]
|
|
1609
|
-
);
|
|
1610
|
-
// ECA continues working as fallback
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
```
|
|
1615
|
-
|
|
1616
|
-
### Strategy 2: Feature Flag Migration
|
|
1617
|
-
|
|
1618
|
-
Migrate specific workflows using feature flags:
|
|
1619
|
-
|
|
1620
|
-
```php
|
|
1621
|
-
/**
|
|
1622
|
-
* Feature-flagged migration.
|
|
1623
|
-
*/
|
|
1624
|
-
function mymodule_entity_presave(EntityInterface $entity) {
|
|
1625
|
-
$features = \Drupal::service('feature_flags');
|
|
1626
|
-
|
|
1627
|
-
if ($features->isEnabled('ossa_content_moderation')) {
|
|
1628
|
-
// Use OSSA agent
|
|
1629
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
1630
|
-
$ossaService->triggerCapability('drupal-content-moderator', 'moderate_article_presave', $data);
|
|
1631
|
-
} else {
|
|
1632
|
-
// Use existing ECA workflow
|
|
1633
|
-
// ECA handles this automatically
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
```
|
|
1637
|
-
|
|
1638
|
-
### Strategy 3: Webhook-Based Integration
|
|
1639
|
-
|
|
1640
|
-
Use webhooks for loose coupling:
|
|
1641
|
-
|
|
1642
|
-
```yaml
|
|
1643
|
-
# OSSA agent with webhook
|
|
1644
|
-
integration:
|
|
1645
|
-
protocol: http
|
|
1646
|
-
endpoints:
|
|
1647
|
-
base_url: http://ossa-gateway:8080
|
|
1648
|
-
webhook: /api/v1/drupal/events
|
|
1649
|
-
auth:
|
|
1650
|
-
type: api_key
|
|
1651
|
-
```
|
|
1652
|
-
|
|
1653
|
-
```php
|
|
1654
|
-
/**
|
|
1655
|
-
* Webhook integration.
|
|
1656
|
-
*/
|
|
1657
|
-
function mymodule_entity_presave(EntityInterface $entity) {
|
|
1658
|
-
$webhook_url = \Drupal::config('ossa_integration.settings')->get('webhook_url');
|
|
1659
|
-
|
|
1660
|
-
$client = \Drupal::httpClient();
|
|
1661
|
-
$client->postAsync($webhook_url, [
|
|
1662
|
-
'json' => [
|
|
1663
|
-
'event' => 'entity.presave',
|
|
1664
|
-
'entity_type' => $entity->getEntityTypeId(),
|
|
1665
|
-
'entity_id' => $entity->id(),
|
|
1666
|
-
'data' => $entity->toArray(),
|
|
1667
|
-
],
|
|
1668
|
-
'headers' => [
|
|
1669
|
-
'X-API-Key' => getenv('OSSA_API_KEY'),
|
|
1670
|
-
],
|
|
1671
|
-
]);
|
|
1672
|
-
}
|
|
1673
|
-
```
|
|
1674
|
-
|
|
1675
|
-
### Strategy 4: Event Queue Integration
|
|
1676
|
-
|
|
1677
|
-
Use message queues for asynchronous processing:
|
|
1678
|
-
|
|
1679
|
-
```yaml
|
|
1680
|
-
# OSSA agent with queue consumer
|
|
1681
|
-
runtime:
|
|
1682
|
-
type: k8s
|
|
1683
|
-
requirements:
|
|
1684
|
-
packages:
|
|
1685
|
-
- bull
|
|
1686
|
-
- ioredis
|
|
1687
|
-
```
|
|
1688
|
-
|
|
1689
|
-
```php
|
|
1690
|
-
/**
|
|
1691
|
-
* Queue-based integration.
|
|
1692
|
-
*/
|
|
1693
|
-
function mymodule_entity_presave(EntityInterface $entity) {
|
|
1694
|
-
/** @var \Drupal\Core\Queue\QueueFactory $queueFactory */
|
|
1695
|
-
$queueFactory = \Drupal::service('queue');
|
|
1696
|
-
$queue = $queueFactory->get('ossa_events');
|
|
1697
|
-
|
|
1698
|
-
$queue->createItem([
|
|
1699
|
-
'agent_id' => 'drupal-content-moderator',
|
|
1700
|
-
'capability' => 'moderate_article_presave',
|
|
1701
|
-
'data' => [
|
|
1702
|
-
'entity_id' => $entity->id(),
|
|
1703
|
-
'entity_type' => $entity->getEntityTypeId(),
|
|
1704
|
-
'timestamp' => time(),
|
|
1705
|
-
],
|
|
1706
|
-
]);
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
/**
|
|
1710
|
-
* Implements hook_cron().
|
|
1711
|
-
*/
|
|
1712
|
-
function mymodule_cron() {
|
|
1713
|
-
$queue = \Drupal::queue('ossa_events');
|
|
1714
|
-
$ossaService = \Drupal::service('ossa_integration.agent_service');
|
|
1715
|
-
|
|
1716
|
-
while ($item = $queue->claimItem()) {
|
|
1717
|
-
try {
|
|
1718
|
-
$ossaService->triggerCapability(
|
|
1719
|
-
$item->data['agent_id'],
|
|
1720
|
-
$item->data['capability'],
|
|
1721
|
-
$item->data['data']
|
|
1722
|
-
);
|
|
1723
|
-
$queue->deleteItem($item);
|
|
1724
|
-
} catch (\Exception $e) {
|
|
1725
|
-
$queue->releaseItem($item);
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
```
|
|
1730
|
-
|
|
1731
|
-
---
|
|
1732
|
-
|
|
1733
|
-
## Best Practices
|
|
1734
|
-
|
|
1735
|
-
### 1. Start Small
|
|
1736
|
-
- Migrate simplest workflows first
|
|
1737
|
-
- Validate each migration thoroughly
|
|
1738
|
-
- Use parallel operation during transition
|
|
1739
|
-
|
|
1740
|
-
### 2. Maintain ECA as Fallback
|
|
1741
|
-
- Keep ECA models active during migration
|
|
1742
|
-
- Use try-catch blocks around OSSA calls
|
|
1743
|
-
- Implement graceful degradation
|
|
1744
|
-
|
|
1745
|
-
### 3. Use Proper Error Handling
|
|
1746
|
-
|
|
1747
|
-
```php
|
|
1748
|
-
try {
|
|
1749
|
-
$result = $ossaService->triggerCapability($agentId, $capability, $data);
|
|
1750
|
-
} catch (RequestException $e) {
|
|
1751
|
-
\Drupal::logger('ossa')->error(
|
|
1752
|
-
'OSSA agent error: @message. Falling back to ECA.',
|
|
1753
|
-
['@message' => $e->getMessage()]
|
|
1754
|
-
);
|
|
1755
|
-
// ECA continues automatically
|
|
1756
|
-
return;
|
|
1757
|
-
} catch (\Exception $e) {
|
|
1758
|
-
// Handle other exceptions
|
|
1759
|
-
}
|
|
1760
|
-
```
|
|
1761
|
-
|
|
1762
|
-
### 4. Leverage OSSA Monitoring
|
|
1763
|
-
|
|
1764
|
-
```yaml
|
|
1765
|
-
monitoring:
|
|
1766
|
-
traces: true
|
|
1767
|
-
metrics: true
|
|
1768
|
-
logs: true
|
|
1769
|
-
phoenix_arise:
|
|
1770
|
-
enabled: true
|
|
1771
|
-
project: drupal-integration
|
|
1772
|
-
```
|
|
1773
|
-
|
|
1774
|
-
### 5. Document Data Mappings
|
|
1775
|
-
|
|
1776
|
-
Create a mapping document for each workflow:
|
|
1777
|
-
|
|
1778
|
-
```yaml
|
|
1779
|
-
# workflow-mapping.yaml
|
|
1780
|
-
eca_model: article_moderation.eca.yml
|
|
1781
|
-
ossa_agent: drupal-content-moderator
|
|
1782
|
-
|
|
1783
|
-
mappings:
|
|
1784
|
-
events:
|
|
1785
|
-
- eca: entity:presave:node:article
|
|
1786
|
-
ossa: POST /api/v1/drupal/moderate
|
|
1787
|
-
hook: hook_entity_presave()
|
|
1788
|
-
|
|
1789
|
-
conditions:
|
|
1790
|
-
- eca: entity_field_value_compare
|
|
1791
|
-
ossa: input_schema.properties.moderation_state.enum
|
|
1792
|
-
|
|
1793
|
-
actions:
|
|
1794
|
-
- eca: eca_content:flag_for_review
|
|
1795
|
-
ossa: capability.moderate_article_presave
|
|
1796
|
-
```
|
|
1797
|
-
|
|
1798
|
-
### 6. Test Thoroughly
|
|
1799
|
-
|
|
1800
|
-
```bash
|
|
1801
|
-
# Test OSSA agent locally
|
|
1802
|
-
docker run -p 3200:3200 ossa/drupal-moderator:1.0.0
|
|
1803
|
-
|
|
1804
|
-
# Validate manifest
|
|
1805
|
-
ossa validate drupal-content-moderator.ossa.yaml
|
|
1806
|
-
|
|
1807
|
-
# Test capability
|
|
1808
|
-
curl -X POST http://localhost:3200/api/v1/drupal/moderate \
|
|
1809
|
-
-H "X-API-Key: test-key" \
|
|
1810
|
-
-H "Content-Type: application/json" \
|
|
1811
|
-
-d '{"entity_id": 123, "moderation_state": "needs_review"}'
|
|
1812
|
-
```
|
|
1813
|
-
|
|
1814
|
-
### 7. Use BuildKit CLI
|
|
1815
|
-
|
|
1816
|
-
```bash
|
|
1817
|
-
# Create OSSA agent from template
|
|
1818
|
-
buildkit agents create drupal-moderator --type worker
|
|
1819
|
-
|
|
1820
|
-
# Validate agent
|
|
1821
|
-
buildkit agents validate .agents/workers/drupal-moderator
|
|
1822
|
-
|
|
1823
|
-
# Deploy agent
|
|
1824
|
-
buildkit golden deploy --env dev
|
|
1825
|
-
```
|
|
1826
|
-
|
|
1827
|
-
---
|
|
1828
|
-
|
|
1829
|
-
## Troubleshooting
|
|
1830
|
-
|
|
1831
|
-
### Issue: OSSA Agent Not Responding
|
|
1832
|
-
|
|
1833
|
-
**Symptoms:**
|
|
1834
|
-
- Drupal hook triggers but no agent response
|
|
1835
|
-
- Timeout errors in logs
|
|
1836
|
-
|
|
1837
|
-
**Solutions:**
|
|
1838
|
-
|
|
1839
|
-
1. Check agent health:
|
|
1840
|
-
```bash
|
|
1841
|
-
curl http://drupal-moderator:3200/health
|
|
1842
|
-
```
|
|
1843
|
-
|
|
1844
|
-
2. Verify network connectivity:
|
|
1845
|
-
```bash
|
|
1846
|
-
kubectl get pods -n ossa
|
|
1847
|
-
kubectl logs deployment/drupal-moderator
|
|
1848
|
-
```
|
|
1849
|
-
|
|
1850
|
-
3. Check API key:
|
|
1851
|
-
```php
|
|
1852
|
-
$api_key = getenv('OSSA_API_KEY');
|
|
1853
|
-
if (empty($api_key)) {
|
|
1854
|
-
\Drupal::logger('ossa')->error('OSSA_API_KEY not set');
|
|
1855
|
-
}
|
|
1856
|
-
```
|
|
1857
|
-
|
|
1858
|
-
### Issue: Schema Validation Failures
|
|
1859
|
-
|
|
1860
|
-
**Symptoms:**
|
|
1861
|
-
- 400 Bad Request errors
|
|
1862
|
-
- "Invalid input schema" messages
|
|
1863
|
-
|
|
1864
|
-
**Solutions:**
|
|
1865
|
-
|
|
1866
|
-
1. Validate input data structure:
|
|
1867
|
-
```php
|
|
1868
|
-
$data = [
|
|
1869
|
-
'entity_id' => $entity->id(),
|
|
1870
|
-
'moderation_state' => $entity->get('moderation_state')->value,
|
|
1871
|
-
// Ensure all required fields present
|
|
1872
|
-
];
|
|
1873
|
-
|
|
1874
|
-
\Drupal::logger('ossa')->debug('Sending data: @data', [
|
|
1875
|
-
'@data' => json_encode($data, JSON_PRETTY_PRINT),
|
|
1876
|
-
]);
|
|
1877
|
-
```
|
|
1878
|
-
|
|
1879
|
-
2. Test with minimal data:
|
|
1880
|
-
```bash
|
|
1881
|
-
curl -X POST http://localhost:3200/api/v1/drupal/moderate \
|
|
1882
|
-
-H "Content-Type: application/json" \
|
|
1883
|
-
-d '{"entity_id": 1, "moderation_state": "draft", "author_experience_level": "junior", "title": "Test", "author_name": "Test User"}'
|
|
1884
|
-
```
|
|
1885
|
-
|
|
1886
|
-
### Issue: Performance Degradation
|
|
1887
|
-
|
|
1888
|
-
**Symptoms:**
|
|
1889
|
-
- Slow entity saves
|
|
1890
|
-
- Increased page load times
|
|
1891
|
-
|
|
1892
|
-
**Solutions:**
|
|
1893
|
-
|
|
1894
|
-
1. Use async/queue-based processing:
|
|
1895
|
-
```php
|
|
1896
|
-
// Don't wait for OSSA response
|
|
1897
|
-
$client->postAsync($url, ['json' => $data]);
|
|
1898
|
-
```
|
|
1899
|
-
|
|
1900
|
-
2. Add caching:
|
|
1901
|
-
```yaml
|
|
1902
|
-
# In OSSA agent
|
|
1903
|
-
monitoring:
|
|
1904
|
-
cache:
|
|
1905
|
-
enabled: true
|
|
1906
|
-
ttl: 300
|
|
1907
|
-
```
|
|
1908
|
-
|
|
1909
|
-
3. Optimize agent resources:
|
|
1910
|
-
```yaml
|
|
1911
|
-
runtime:
|
|
1912
|
-
resources:
|
|
1913
|
-
cpu: '2000m'
|
|
1914
|
-
memory: '2Gi'
|
|
1915
|
-
```
|
|
1916
|
-
|
|
1917
|
-
### Issue: ECA and OSSA Conflicts
|
|
1918
|
-
|
|
1919
|
-
**Symptoms:**
|
|
1920
|
-
- Duplicate actions
|
|
1921
|
-
- Race conditions
|
|
1922
|
-
|
|
1923
|
-
**Solutions:**
|
|
1924
|
-
|
|
1925
|
-
1. Disable ECA model:
|
|
1926
|
-
```bash
|
|
1927
|
-
drush eca:disable article_moderation
|
|
1928
|
-
```
|
|
1929
|
-
|
|
1930
|
-
2. Use conditional logic:
|
|
1931
|
-
```php
|
|
1932
|
-
if ($features->isEnabled('ossa_moderation')) {
|
|
1933
|
-
// OSSA only
|
|
1934
|
-
return;
|
|
1935
|
-
}
|
|
1936
|
-
// ECA continues
|
|
1937
|
-
```
|
|
1938
|
-
|
|
1939
|
-
---
|
|
1940
|
-
|
|
1941
|
-
## Additional Resources
|
|
1942
|
-
|
|
1943
|
-
### Documentation
|
|
1944
|
-
- [OSSA Specification](https://github.com/blueflyio/openstandardagents/wiki/home)
|
|
1945
|
-
- [Drupal ECA Guide](https://ecaguide.org/)
|
|
1946
|
-
- [BuildKit CLI Reference](https://github.com/blueflyio/documentation/-/wikis/BuildKit-CLI-Reference)
|
|
1947
|
-
|
|
1948
|
-
### Tools
|
|
1949
|
-
- OSSA CLI: `npm install -g @ossa/cli`
|
|
1950
|
-
- BuildKit: `npm install -g @llm/agent-buildkit`
|
|
1951
|
-
- OSSA Validator: `ossa validate <file>`
|
|
1952
|
-
|
|
1953
|
-
### Examples
|
|
1954
|
-
- [OSSA Example Agents](https://github.com/blueflyio/openstandardagents/tree/main/examples)
|
|
1955
|
-
- [Drupal Integration Module](https://github.com/blueflyio/drupal/ossa_integration)
|
|
1956
|
-
|
|
1957
|
-
### Support
|
|
1958
|
-
- [GitLab Issues](https://github.com/blueflyio/documentation/-/issues)
|
|
1959
|
-
- [OSSA Discussions](https://github.com/blueflyio/openstandardagents/issues)
|
|
1960
|
-
|
|
1961
|
-
---
|
|
1962
|
-
|
|
1963
|
-
## Migration Checklist
|
|
1964
|
-
|
|
1965
|
-
### Pre-Migration
|
|
1966
|
-
- [ ] Inventory all ECA models
|
|
1967
|
-
- [ ] Document event/condition/action mappings
|
|
1968
|
-
- [ ] Identify external dependencies
|
|
1969
|
-
- [ ] Review Drupal hook usage
|
|
1970
|
-
- [ ] Plan rollback strategy
|
|
1971
|
-
|
|
1972
|
-
### Agent Development
|
|
1973
|
-
- [ ] Create OSSA agent manifests
|
|
1974
|
-
- [ ] Define capabilities with schemas
|
|
1975
|
-
- [ ] Map ECA conditions to schema validations
|
|
1976
|
-
- [ ] Map ECA actions to agent capabilities
|
|
1977
|
-
- [ ] Add monitoring and observability
|
|
1978
|
-
- [ ] Configure policies and compliance
|
|
1979
|
-
|
|
1980
|
-
### Integration
|
|
1981
|
-
- [ ] Implement Drupal integration module
|
|
1982
|
-
- [ ] Create hook implementations
|
|
1983
|
-
- [ ] Add OSSA service class
|
|
1984
|
-
- [ ] Configure API authentication
|
|
1985
|
-
- [ ] Implement error handling
|
|
1986
|
-
- [ ] Add logging
|
|
1987
|
-
|
|
1988
|
-
### Testing
|
|
1989
|
-
- [ ] Validate OSSA manifests
|
|
1990
|
-
- [ ] Test agents locally
|
|
1991
|
-
- [ ] Test Drupal integration
|
|
1992
|
-
- [ ] Performance testing
|
|
1993
|
-
- [ ] Load testing
|
|
1994
|
-
- [ ] Integration testing
|
|
1995
|
-
|
|
1996
|
-
### Deployment
|
|
1997
|
-
- [ ] Deploy OSSA agents to environment
|
|
1998
|
-
- [ ] Configure environment variables
|
|
1999
|
-
- [ ] Enable feature flags
|
|
2000
|
-
- [ ] Monitor agent health
|
|
2001
|
-
- [ ] Monitor Drupal logs
|
|
2002
|
-
- [ ] Validate workflows
|
|
2003
|
-
|
|
2004
|
-
### Post-Migration
|
|
2005
|
-
- [ ] Compare ECA vs OSSA behavior
|
|
2006
|
-
- [ ] Monitor performance metrics
|
|
2007
|
-
- [ ] Collect user feedback
|
|
2008
|
-
- [ ] Disable ECA models (after validation)
|
|
2009
|
-
- [ ] Update documentation
|
|
2010
|
-
- [ ] Train team on OSSA
|
|
2011
|
-
|
|
2012
|
-
---
|
|
2013
|
-
|
|
2014
|
-
**Version:** 1.0.0
|
|
2015
|
-
**Last Updated:** 2025-11-10
|
|
2016
|
-
**Maintainer:** LLM Platform Team
|
|
2017
|
-
**License:** Apache-2.0
|