claude-autopm 2.8.2 → 2.8.3
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/README.md +399 -637
- package/package.json +2 -1
- package/packages/plugin-ai/LICENSE +21 -0
- package/packages/plugin-ai/README.md +316 -0
- package/packages/plugin-ai/agents/anthropic-claude-expert.md +579 -0
- package/packages/plugin-ai/agents/azure-openai-expert.md +1411 -0
- package/packages/plugin-ai/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-ai/agents/google-a2a-expert.md +1445 -0
- package/packages/plugin-ai/agents/huggingface-expert.md +2131 -0
- package/packages/plugin-ai/agents/langchain-expert.md +1427 -0
- package/packages/plugin-ai/agents/langgraph-workflow-expert.md +520 -0
- package/packages/plugin-ai/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-ai/commands/a2a-setup.md +886 -0
- package/packages/plugin-ai/commands/ai-model-deployment.md +481 -0
- package/packages/plugin-ai/commands/anthropic-optimize.md +793 -0
- package/packages/plugin-ai/commands/huggingface-deploy.md +789 -0
- package/packages/plugin-ai/commands/langchain-optimize.md +807 -0
- package/packages/plugin-ai/commands/llm-optimize.md +348 -0
- package/packages/plugin-ai/commands/openai-optimize.md +863 -0
- package/packages/plugin-ai/commands/rag-optimize.md +841 -0
- package/packages/plugin-ai/commands/rag-setup-scaffold.md +382 -0
- package/packages/plugin-ai/package.json +66 -0
- package/packages/plugin-ai/plugin.json +519 -0
- package/packages/plugin-ai/rules/ai-model-standards.md +449 -0
- package/packages/plugin-ai/rules/prompt-engineering-standards.md +509 -0
- package/packages/plugin-ai/scripts/examples/huggingface-inference-example.py +145 -0
- package/packages/plugin-ai/scripts/examples/langchain-rag-example.py +366 -0
- package/packages/plugin-ai/scripts/examples/mlflow-tracking-example.py +224 -0
- package/packages/plugin-ai/scripts/examples/openai-chat-example.py +425 -0
- package/packages/plugin-cloud/README.md +268 -0
- package/packages/plugin-cloud/agents/README.md +55 -0
- package/packages/plugin-cloud/agents/aws-cloud-architect.md +521 -0
- package/packages/plugin-cloud/agents/azure-cloud-architect.md +436 -0
- package/packages/plugin-cloud/agents/gcp-cloud-architect.md +385 -0
- package/packages/plugin-cloud/agents/gcp-cloud-functions-engineer.md +306 -0
- package/packages/plugin-cloud/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-cloud/agents/kubernetes-orchestrator.md +566 -0
- package/packages/plugin-cloud/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-cloud/agents/terraform-infrastructure-expert.md +454 -0
- package/packages/plugin-cloud/commands/cloud-cost-optimize.md +243 -0
- package/packages/plugin-cloud/commands/cloud-validate.md +196 -0
- package/packages/plugin-cloud/commands/infra-deploy.md +38 -0
- package/packages/plugin-cloud/commands/k8s-deploy.md +37 -0
- package/packages/plugin-cloud/commands/ssh-security.md +65 -0
- package/packages/plugin-cloud/commands/traefik-setup.md +65 -0
- package/packages/plugin-cloud/hooks/pre-cloud-deploy.js +456 -0
- package/packages/plugin-cloud/package.json +64 -0
- package/packages/plugin-cloud/plugin.json +338 -0
- package/packages/plugin-cloud/rules/cloud-security-compliance.md +313 -0
- package/packages/plugin-cloud/rules/infrastructure-pipeline.md +128 -0
- package/packages/plugin-cloud/scripts/examples/aws-validate.sh +30 -0
- package/packages/plugin-cloud/scripts/examples/azure-setup.sh +33 -0
- package/packages/plugin-cloud/scripts/examples/gcp-setup.sh +39 -0
- package/packages/plugin-cloud/scripts/examples/k8s-validate.sh +40 -0
- package/packages/plugin-cloud/scripts/examples/terraform-init.sh +26 -0
- package/packages/plugin-core/README.md +274 -0
- package/packages/plugin-core/agents/core/agent-manager.md +296 -0
- package/packages/plugin-core/agents/core/code-analyzer.md +131 -0
- package/packages/plugin-core/agents/core/file-analyzer.md +162 -0
- package/packages/plugin-core/agents/core/test-runner.md +200 -0
- package/packages/plugin-core/commands/code-rabbit.md +128 -0
- package/packages/plugin-core/commands/prompt.md +9 -0
- package/packages/plugin-core/commands/re-init.md +9 -0
- package/packages/plugin-core/hooks/context7-reminder.md +29 -0
- package/packages/plugin-core/hooks/enforce-agents.js +125 -0
- package/packages/plugin-core/hooks/enforce-agents.sh +35 -0
- package/packages/plugin-core/hooks/pre-agent-context7.js +224 -0
- package/packages/plugin-core/hooks/pre-command-context7.js +229 -0
- package/packages/plugin-core/hooks/strict-enforce-agents.sh +39 -0
- package/packages/plugin-core/hooks/test-hook.sh +21 -0
- package/packages/plugin-core/hooks/unified-context7-enforcement.sh +38 -0
- package/packages/plugin-core/package.json +45 -0
- package/packages/plugin-core/plugin.json +387 -0
- package/packages/plugin-core/rules/agent-coordination.md +549 -0
- package/packages/plugin-core/rules/agent-mandatory.md +170 -0
- package/packages/plugin-core/rules/ai-integration-patterns.md +219 -0
- package/packages/plugin-core/rules/command-pipelines.md +208 -0
- package/packages/plugin-core/rules/context-optimization.md +176 -0
- package/packages/plugin-core/rules/context7-enforcement.md +327 -0
- package/packages/plugin-core/rules/datetime.md +122 -0
- package/packages/plugin-core/rules/definition-of-done.md +272 -0
- package/packages/plugin-core/rules/development-environments.md +19 -0
- package/packages/plugin-core/rules/development-workflow.md +198 -0
- package/packages/plugin-core/rules/framework-path-rules.md +180 -0
- package/packages/plugin-core/rules/frontmatter-operations.md +64 -0
- package/packages/plugin-core/rules/git-strategy.md +237 -0
- package/packages/plugin-core/rules/golden-rules.md +181 -0
- package/packages/plugin-core/rules/naming-conventions.md +111 -0
- package/packages/plugin-core/rules/no-pr-workflow.md +183 -0
- package/packages/plugin-core/rules/performance-guidelines.md +403 -0
- package/packages/plugin-core/rules/pipeline-mandatory.md +109 -0
- package/packages/plugin-core/rules/security-checklist.md +318 -0
- package/packages/plugin-core/rules/standard-patterns.md +197 -0
- package/packages/plugin-core/rules/strip-frontmatter.md +85 -0
- package/packages/plugin-core/rules/tdd.enforcement.md +103 -0
- package/packages/plugin-core/rules/use-ast-grep.md +113 -0
- package/packages/plugin-core/scripts/lib/datetime-utils.sh +254 -0
- package/packages/plugin-core/scripts/lib/frontmatter-utils.sh +294 -0
- package/packages/plugin-core/scripts/lib/github-utils.sh +221 -0
- package/packages/plugin-core/scripts/lib/logging-utils.sh +199 -0
- package/packages/plugin-core/scripts/lib/validation-utils.sh +339 -0
- package/packages/plugin-core/scripts/mcp/add.sh +7 -0
- package/packages/plugin-core/scripts/mcp/disable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/enable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/list.sh +7 -0
- package/packages/plugin-core/scripts/mcp/sync.sh +8 -0
- package/packages/plugin-data/README.md +315 -0
- package/packages/plugin-data/agents/airflow-orchestration-expert.md +158 -0
- package/packages/plugin-data/agents/kedro-pipeline-expert.md +304 -0
- package/packages/plugin-data/agents/langgraph-workflow-expert.md +530 -0
- package/packages/plugin-data/commands/airflow-dag-scaffold.md +413 -0
- package/packages/plugin-data/commands/kafka-pipeline-scaffold.md +503 -0
- package/packages/plugin-data/package.json +66 -0
- package/packages/plugin-data/plugin.json +294 -0
- package/packages/plugin-data/rules/data-quality-standards.md +373 -0
- package/packages/plugin-data/rules/etl-pipeline-standards.md +255 -0
- package/packages/plugin-data/scripts/examples/airflow-dag-example.py +245 -0
- package/packages/plugin-data/scripts/examples/dbt-transform-example.sql +238 -0
- package/packages/plugin-data/scripts/examples/kafka-streaming-example.py +257 -0
- package/packages/plugin-data/scripts/examples/pandas-etl-example.py +332 -0
- package/packages/plugin-databases/README.md +330 -0
- package/packages/plugin-databases/agents/README.md +50 -0
- package/packages/plugin-databases/agents/bigquery-expert.md +401 -0
- package/packages/plugin-databases/agents/cosmosdb-expert.md +375 -0
- package/packages/plugin-databases/agents/mongodb-expert.md +407 -0
- package/packages/plugin-databases/agents/postgresql-expert.md +329 -0
- package/packages/plugin-databases/agents/redis-expert.md +74 -0
- package/packages/plugin-databases/commands/db-optimize.md +612 -0
- package/packages/plugin-databases/package.json +60 -0
- package/packages/plugin-databases/plugin.json +237 -0
- package/packages/plugin-databases/rules/database-management-strategy.md +146 -0
- package/packages/plugin-databases/rules/database-pipeline.md +316 -0
- package/packages/plugin-databases/scripts/examples/bigquery-cost-analyze.sh +160 -0
- package/packages/plugin-databases/scripts/examples/cosmosdb-ru-optimize.sh +163 -0
- package/packages/plugin-databases/scripts/examples/mongodb-shard-check.sh +120 -0
- package/packages/plugin-databases/scripts/examples/postgres-index-analyze.sh +95 -0
- package/packages/plugin-databases/scripts/examples/redis-cache-stats.sh +121 -0
- package/packages/plugin-devops/README.md +367 -0
- package/packages/plugin-devops/agents/README.md +52 -0
- package/packages/plugin-devops/agents/azure-devops-specialist.md +308 -0
- package/packages/plugin-devops/agents/docker-containerization-expert.md +298 -0
- package/packages/plugin-devops/agents/github-operations-specialist.md +335 -0
- package/packages/plugin-devops/agents/mcp-context-manager.md +319 -0
- package/packages/plugin-devops/agents/observability-engineer.md +574 -0
- package/packages/plugin-devops/agents/ssh-operations-expert.md +1093 -0
- package/packages/plugin-devops/agents/traefik-proxy-expert.md +444 -0
- package/packages/plugin-devops/commands/ci-pipeline-create.md +581 -0
- package/packages/plugin-devops/commands/docker-optimize.md +493 -0
- package/packages/plugin-devops/commands/workflow-create.md +42 -0
- package/packages/plugin-devops/hooks/pre-docker-build.js +472 -0
- package/packages/plugin-devops/package.json +61 -0
- package/packages/plugin-devops/plugin.json +302 -0
- package/packages/plugin-devops/rules/ci-cd-kubernetes-strategy.md +25 -0
- package/packages/plugin-devops/rules/devops-troubleshooting-playbook.md +450 -0
- package/packages/plugin-devops/rules/docker-first-development.md +404 -0
- package/packages/plugin-devops/rules/github-operations.md +92 -0
- package/packages/plugin-devops/scripts/examples/docker-build-multistage.sh +43 -0
- package/packages/plugin-devops/scripts/examples/docker-compose-validate.sh +74 -0
- package/packages/plugin-devops/scripts/examples/github-workflow-validate.sh +48 -0
- package/packages/plugin-devops/scripts/examples/prometheus-health-check.sh +58 -0
- package/packages/plugin-devops/scripts/examples/ssh-key-setup.sh +74 -0
- package/packages/plugin-frameworks/README.md +309 -0
- package/packages/plugin-frameworks/agents/README.md +64 -0
- package/packages/plugin-frameworks/agents/e2e-test-engineer.md +579 -0
- package/packages/plugin-frameworks/agents/nats-messaging-expert.md +254 -0
- package/packages/plugin-frameworks/agents/react-frontend-engineer.md +393 -0
- package/packages/plugin-frameworks/agents/react-ui-expert.md +226 -0
- package/packages/plugin-frameworks/agents/tailwindcss-expert.md +1021 -0
- package/packages/plugin-frameworks/agents/ux-design-expert.md +244 -0
- package/packages/plugin-frameworks/commands/app-scaffold.md +50 -0
- package/packages/plugin-frameworks/commands/nextjs-optimize.md +692 -0
- package/packages/plugin-frameworks/commands/react-optimize.md +583 -0
- package/packages/plugin-frameworks/commands/tailwind-system.md +64 -0
- package/packages/plugin-frameworks/package.json +59 -0
- package/packages/plugin-frameworks/plugin.json +224 -0
- package/packages/plugin-frameworks/rules/performance-guidelines.md +403 -0
- package/packages/plugin-frameworks/rules/ui-development-standards.md +281 -0
- package/packages/plugin-frameworks/rules/ui-framework-rules.md +151 -0
- package/packages/plugin-frameworks/scripts/examples/react-component-perf.sh +34 -0
- package/packages/plugin-frameworks/scripts/examples/tailwind-optimize.sh +44 -0
- package/packages/plugin-frameworks/scripts/examples/vue-composition-check.sh +41 -0
- package/packages/plugin-languages/README.md +333 -0
- package/packages/plugin-languages/agents/README.md +50 -0
- package/packages/plugin-languages/agents/bash-scripting-expert.md +541 -0
- package/packages/plugin-languages/agents/javascript-frontend-engineer.md +197 -0
- package/packages/plugin-languages/agents/nodejs-backend-engineer.md +226 -0
- package/packages/plugin-languages/agents/python-backend-engineer.md +214 -0
- package/packages/plugin-languages/agents/python-backend-expert.md +289 -0
- package/packages/plugin-languages/commands/javascript-optimize.md +636 -0
- package/packages/plugin-languages/commands/nodejs-api-scaffold.md +341 -0
- package/packages/plugin-languages/commands/nodejs-optimize.md +689 -0
- package/packages/plugin-languages/commands/python-api-scaffold.md +261 -0
- package/packages/plugin-languages/commands/python-optimize.md +593 -0
- package/packages/plugin-languages/package.json +65 -0
- package/packages/plugin-languages/plugin.json +265 -0
- package/packages/plugin-languages/rules/code-quality-standards.md +496 -0
- package/packages/plugin-languages/rules/testing-standards.md +768 -0
- package/packages/plugin-languages/scripts/examples/bash-production-script.sh +520 -0
- package/packages/plugin-languages/scripts/examples/javascript-es6-patterns.js +291 -0
- package/packages/plugin-languages/scripts/examples/nodejs-async-iteration.js +360 -0
- package/packages/plugin-languages/scripts/examples/python-async-patterns.py +289 -0
- package/packages/plugin-languages/scripts/examples/typescript-patterns.ts +432 -0
- package/packages/plugin-ml/README.md +430 -0
- package/packages/plugin-ml/agents/automl-expert.md +326 -0
- package/packages/plugin-ml/agents/computer-vision-expert.md +550 -0
- package/packages/plugin-ml/agents/gradient-boosting-expert.md +455 -0
- package/packages/plugin-ml/agents/neural-network-architect.md +1228 -0
- package/packages/plugin-ml/agents/nlp-transformer-expert.md +584 -0
- package/packages/plugin-ml/agents/pytorch-expert.md +412 -0
- package/packages/plugin-ml/agents/reinforcement-learning-expert.md +2088 -0
- package/packages/plugin-ml/agents/scikit-learn-expert.md +228 -0
- package/packages/plugin-ml/agents/tensorflow-keras-expert.md +509 -0
- package/packages/plugin-ml/agents/time-series-expert.md +303 -0
- package/packages/plugin-ml/commands/ml-automl.md +572 -0
- package/packages/plugin-ml/commands/ml-train-optimize.md +657 -0
- package/packages/plugin-ml/package.json +52 -0
- package/packages/plugin-ml/plugin.json +338 -0
- package/packages/plugin-pm/README.md +368 -0
- package/packages/plugin-pm/claudeautopm-plugin-pm-2.0.0.tgz +0 -0
- package/packages/plugin-pm/commands/azure/COMMANDS.md +107 -0
- package/packages/plugin-pm/commands/azure/COMMAND_MAPPING.md +252 -0
- package/packages/plugin-pm/commands/azure/INTEGRATION_FIX.md +103 -0
- package/packages/plugin-pm/commands/azure/README.md +246 -0
- package/packages/plugin-pm/commands/azure/active-work.md +198 -0
- package/packages/plugin-pm/commands/azure/aliases.md +143 -0
- package/packages/plugin-pm/commands/azure/blocked-items.md +287 -0
- package/packages/plugin-pm/commands/azure/clean.md +93 -0
- package/packages/plugin-pm/commands/azure/docs-query.md +48 -0
- package/packages/plugin-pm/commands/azure/feature-decompose.md +380 -0
- package/packages/plugin-pm/commands/azure/feature-list.md +61 -0
- package/packages/plugin-pm/commands/azure/feature-new.md +115 -0
- package/packages/plugin-pm/commands/azure/feature-show.md +205 -0
- package/packages/plugin-pm/commands/azure/feature-start.md +130 -0
- package/packages/plugin-pm/commands/azure/fix-integration-example.md +93 -0
- package/packages/plugin-pm/commands/azure/help.md +150 -0
- package/packages/plugin-pm/commands/azure/import-us.md +269 -0
- package/packages/plugin-pm/commands/azure/init.md +211 -0
- package/packages/plugin-pm/commands/azure/next-task.md +262 -0
- package/packages/plugin-pm/commands/azure/search.md +160 -0
- package/packages/plugin-pm/commands/azure/sprint-status.md +235 -0
- package/packages/plugin-pm/commands/azure/standup.md +260 -0
- package/packages/plugin-pm/commands/azure/sync-all.md +99 -0
- package/packages/plugin-pm/commands/azure/task-analyze.md +186 -0
- package/packages/plugin-pm/commands/azure/task-close.md +329 -0
- package/packages/plugin-pm/commands/azure/task-edit.md +145 -0
- package/packages/plugin-pm/commands/azure/task-list.md +263 -0
- package/packages/plugin-pm/commands/azure/task-new.md +84 -0
- package/packages/plugin-pm/commands/azure/task-reopen.md +79 -0
- package/packages/plugin-pm/commands/azure/task-show.md +126 -0
- package/packages/plugin-pm/commands/azure/task-start.md +301 -0
- package/packages/plugin-pm/commands/azure/task-status.md +65 -0
- package/packages/plugin-pm/commands/azure/task-sync.md +67 -0
- package/packages/plugin-pm/commands/azure/us-edit.md +164 -0
- package/packages/plugin-pm/commands/azure/us-list.md +202 -0
- package/packages/plugin-pm/commands/azure/us-new.md +265 -0
- package/packages/plugin-pm/commands/azure/us-parse.md +253 -0
- package/packages/plugin-pm/commands/azure/us-show.md +188 -0
- package/packages/plugin-pm/commands/azure/us-status.md +320 -0
- package/packages/plugin-pm/commands/azure/validate.md +86 -0
- package/packages/plugin-pm/commands/azure/work-item-sync.md +47 -0
- package/packages/plugin-pm/commands/blocked.md +28 -0
- package/packages/plugin-pm/commands/clean.md +119 -0
- package/packages/plugin-pm/commands/context-create.md +136 -0
- package/packages/plugin-pm/commands/context-prime.md +170 -0
- package/packages/plugin-pm/commands/context-update.md +292 -0
- package/packages/plugin-pm/commands/context.md +28 -0
- package/packages/plugin-pm/commands/epic-close.md +86 -0
- package/packages/plugin-pm/commands/epic-decompose.md +370 -0
- package/packages/plugin-pm/commands/epic-edit.md +83 -0
- package/packages/plugin-pm/commands/epic-list.md +30 -0
- package/packages/plugin-pm/commands/epic-merge.md +222 -0
- package/packages/plugin-pm/commands/epic-oneshot.md +119 -0
- package/packages/plugin-pm/commands/epic-refresh.md +119 -0
- package/packages/plugin-pm/commands/epic-show.md +28 -0
- package/packages/plugin-pm/commands/epic-split.md +120 -0
- package/packages/plugin-pm/commands/epic-start.md +195 -0
- package/packages/plugin-pm/commands/epic-status.md +28 -0
- package/packages/plugin-pm/commands/epic-sync-modular.md +338 -0
- package/packages/plugin-pm/commands/epic-sync-original.md +473 -0
- package/packages/plugin-pm/commands/epic-sync.md +486 -0
- package/packages/plugin-pm/commands/github/workflow-create.md +42 -0
- package/packages/plugin-pm/commands/help.md +28 -0
- package/packages/plugin-pm/commands/import.md +115 -0
- package/packages/plugin-pm/commands/in-progress.md +28 -0
- package/packages/plugin-pm/commands/init.md +28 -0
- package/packages/plugin-pm/commands/issue-analyze.md +202 -0
- package/packages/plugin-pm/commands/issue-close.md +119 -0
- package/packages/plugin-pm/commands/issue-edit.md +93 -0
- package/packages/plugin-pm/commands/issue-reopen.md +87 -0
- package/packages/plugin-pm/commands/issue-show.md +41 -0
- package/packages/plugin-pm/commands/issue-start.md +234 -0
- package/packages/plugin-pm/commands/issue-status.md +95 -0
- package/packages/plugin-pm/commands/issue-sync.md +411 -0
- package/packages/plugin-pm/commands/next.md +28 -0
- package/packages/plugin-pm/commands/prd-edit.md +82 -0
- package/packages/plugin-pm/commands/prd-list.md +28 -0
- package/packages/plugin-pm/commands/prd-new.md +55 -0
- package/packages/plugin-pm/commands/prd-parse.md +42 -0
- package/packages/plugin-pm/commands/prd-status.md +28 -0
- package/packages/plugin-pm/commands/search.md +28 -0
- package/packages/plugin-pm/commands/standup.md +28 -0
- package/packages/plugin-pm/commands/status.md +28 -0
- package/packages/plugin-pm/commands/sync.md +99 -0
- package/packages/plugin-pm/commands/test-reference-update.md +151 -0
- package/packages/plugin-pm/commands/validate.md +28 -0
- package/packages/plugin-pm/commands/what-next.md +28 -0
- package/packages/plugin-pm/package.json +57 -0
- package/packages/plugin-pm/plugin.json +503 -0
- package/packages/plugin-pm/scripts/pm/analytics.js +425 -0
- package/packages/plugin-pm/scripts/pm/blocked.js +164 -0
- package/packages/plugin-pm/scripts/pm/blocked.sh +78 -0
- package/packages/plugin-pm/scripts/pm/clean.js +464 -0
- package/packages/plugin-pm/scripts/pm/context-create.js +216 -0
- package/packages/plugin-pm/scripts/pm/context-prime.js +335 -0
- package/packages/plugin-pm/scripts/pm/context-update.js +344 -0
- package/packages/plugin-pm/scripts/pm/context.js +338 -0
- package/packages/plugin-pm/scripts/pm/epic-close.js +347 -0
- package/packages/plugin-pm/scripts/pm/epic-edit.js +382 -0
- package/packages/plugin-pm/scripts/pm/epic-list.js +273 -0
- package/packages/plugin-pm/scripts/pm/epic-list.sh +109 -0
- package/packages/plugin-pm/scripts/pm/epic-show.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-show.sh +105 -0
- package/packages/plugin-pm/scripts/pm/epic-split.js +522 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.js +183 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.sh +94 -0
- package/packages/plugin-pm/scripts/pm/epic-status.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-status.sh +104 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/README.md +208 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-epic-issue.sh +77 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-task-issues.sh +86 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-epic-file.sh +79 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-references.sh +89 -0
- package/packages/plugin-pm/scripts/pm/epic-sync.sh +137 -0
- package/packages/plugin-pm/scripts/pm/help.js +92 -0
- package/packages/plugin-pm/scripts/pm/help.sh +90 -0
- package/packages/plugin-pm/scripts/pm/in-progress.js +178 -0
- package/packages/plugin-pm/scripts/pm/in-progress.sh +93 -0
- package/packages/plugin-pm/scripts/pm/init.js +321 -0
- package/packages/plugin-pm/scripts/pm/init.sh +178 -0
- package/packages/plugin-pm/scripts/pm/issue-close.js +232 -0
- package/packages/plugin-pm/scripts/pm/issue-edit.js +310 -0
- package/packages/plugin-pm/scripts/pm/issue-show.js +272 -0
- package/packages/plugin-pm/scripts/pm/issue-start.js +181 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/format-comment.sh +468 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/gather-updates.sh +460 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/post-comment.sh +330 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/preflight-validation.sh +348 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/update-frontmatter.sh +387 -0
- package/packages/plugin-pm/scripts/pm/lib/README.md +85 -0
- package/packages/plugin-pm/scripts/pm/lib/epic-discovery.js +119 -0
- package/packages/plugin-pm/scripts/pm/lib/logger.js +78 -0
- package/packages/plugin-pm/scripts/pm/next.js +189 -0
- package/packages/plugin-pm/scripts/pm/next.sh +72 -0
- package/packages/plugin-pm/scripts/pm/optimize.js +407 -0
- package/packages/plugin-pm/scripts/pm/pr-create.js +337 -0
- package/packages/plugin-pm/scripts/pm/pr-list.js +257 -0
- package/packages/plugin-pm/scripts/pm/prd-list.js +242 -0
- package/packages/plugin-pm/scripts/pm/prd-list.sh +103 -0
- package/packages/plugin-pm/scripts/pm/prd-new.js +684 -0
- package/packages/plugin-pm/scripts/pm/prd-parse.js +547 -0
- package/packages/plugin-pm/scripts/pm/prd-status.js +152 -0
- package/packages/plugin-pm/scripts/pm/prd-status.sh +63 -0
- package/packages/plugin-pm/scripts/pm/release.js +460 -0
- package/packages/plugin-pm/scripts/pm/search.js +192 -0
- package/packages/plugin-pm/scripts/pm/search.sh +89 -0
- package/packages/plugin-pm/scripts/pm/standup.js +362 -0
- package/packages/plugin-pm/scripts/pm/standup.sh +95 -0
- package/packages/plugin-pm/scripts/pm/status.js +148 -0
- package/packages/plugin-pm/scripts/pm/status.sh +59 -0
- package/packages/plugin-pm/scripts/pm/sync-batch.js +337 -0
- package/packages/plugin-pm/scripts/pm/sync.js +343 -0
- package/packages/plugin-pm/scripts/pm/template-list.js +141 -0
- package/packages/plugin-pm/scripts/pm/template-new.js +366 -0
- package/packages/plugin-pm/scripts/pm/validate.js +274 -0
- package/packages/plugin-pm/scripts/pm/validate.sh +106 -0
- package/packages/plugin-pm/scripts/pm/what-next.js +660 -0
- package/packages/plugin-testing/README.md +401 -0
- package/packages/plugin-testing/agents/frontend-testing-engineer.md +768 -0
- package/packages/plugin-testing/commands/jest-optimize.md +800 -0
- package/packages/plugin-testing/commands/playwright-optimize.md +887 -0
- package/packages/plugin-testing/commands/test-coverage.md +512 -0
- package/packages/plugin-testing/commands/test-performance.md +1041 -0
- package/packages/plugin-testing/commands/test-setup.md +414 -0
- package/packages/plugin-testing/package.json +40 -0
- package/packages/plugin-testing/plugin.json +197 -0
- package/packages/plugin-testing/rules/test-coverage-requirements.md +581 -0
- package/packages/plugin-testing/rules/testing-standards.md +529 -0
- package/packages/plugin-testing/scripts/examples/react-testing-example.test.jsx +460 -0
- package/packages/plugin-testing/scripts/examples/vitest-config-example.js +352 -0
- package/packages/plugin-testing/scripts/examples/vue-testing-example.test.js +586 -0
|
@@ -0,0 +1,1445 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: google-a2a-expert
|
|
3
|
+
description: Use this agent for Google Agent-to-Agent (A2A) protocol implementation including multi-agent orchestration, Vertex AI Agent Builder, ADK integration, and agent collaboration. Expert in A2A protocol, agent cards, inter-agent communication, LangGraph integration, and production deployment. Perfect for building sophisticated multi-agent AI systems with standardized agent interoperability.
|
|
4
|
+
tools: Glob, Grep, LS, Read, WebFetch, TodoWrite, WebSearch, Edit, Write, MultiEdit, Bash, Task, Agent
|
|
5
|
+
model: inherit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Google Agent-to-Agent (A2A) Expert Agent
|
|
9
|
+
|
|
10
|
+
## Identity
|
|
11
|
+
You are the **Google Agent-to-Agent (A2A) Expert Agent**, a specialized AI systems architect with deep expertise in Google's A2A protocol, Vertex AI Agent Builder, and multi-agent orchestration patterns. You excel at designing and implementing agent-to-agent communication systems that enable seamless collaboration across different AI frameworks and platforms.
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
Design, implement, and optimize multi-agent AI systems using Google's A2A protocol with focus on:
|
|
15
|
+
- A2A protocol implementation and agent card design
|
|
16
|
+
- Vertex AI Agent Builder and Agent Engine
|
|
17
|
+
- Multi-agent orchestration with ADK (Agent Development Kit)
|
|
18
|
+
- Integration with LangGraph, LangChain, CrewAI, and other frameworks
|
|
19
|
+
- Agent-to-agent communication patterns and security
|
|
20
|
+
- Production deployment on Google Cloud Platform
|
|
21
|
+
|
|
22
|
+
## Test-Driven Development (TDD) Methodology
|
|
23
|
+
|
|
24
|
+
**MANDATORY**: Follow strict TDD principles for all development:
|
|
25
|
+
1. **Write failing tests FIRST** - Before implementing any functionality
|
|
26
|
+
2. **Red-Green-Refactor cycle** - Test fails → Make it pass → Improve code
|
|
27
|
+
3. **One test at a time** - Focus on small, incremental development
|
|
28
|
+
4. **100% coverage for new code** - All new features must have complete test coverage
|
|
29
|
+
5. **Tests as documentation** - Tests should clearly document expected behavior
|
|
30
|
+
|
|
31
|
+
## Documentation Access via MCP Context7
|
|
32
|
+
|
|
33
|
+
**MANDATORY:** Before implementing A2A solutions, query Context7 for latest patterns and best practices.
|
|
34
|
+
|
|
35
|
+
**Documentation Queries:**
|
|
36
|
+
- `mcp://context7/googleapis/google-cloud-python/vertexai` - Vertex AI Python SDK documentation and patterns
|
|
37
|
+
- `mcp://context7/websites/cloud_google/vertex-ai` - Official Vertex AI documentation and Agent Builder
|
|
38
|
+
- `mcp://context7/google/generative-ai-python` - Gemini integration and generative AI capabilities
|
|
39
|
+
- `mcp://context7/websites/a2aprotocol` - A2A protocol specification and implementation guide
|
|
40
|
+
- `mcp://context7/langgraph/langgraph` - LangGraph integration patterns for multi-agent workflows
|
|
41
|
+
- `mcp://context7/langchain/langchain` - LangChain integration for agent tooling
|
|
42
|
+
|
|
43
|
+
**Why This is Required:**
|
|
44
|
+
- A2A protocol is rapidly evolving (donated to Linux Foundation June 2025)
|
|
45
|
+
- Agent card schema and authentication patterns have specific requirements
|
|
46
|
+
- Vertex AI Agent Builder features are continuously updated
|
|
47
|
+
- Multi-agent orchestration patterns vary by framework
|
|
48
|
+
- Security and authentication schemes differ by deployment
|
|
49
|
+
- Integration patterns with LangGraph/LangChain require current documentation
|
|
50
|
+
|
|
51
|
+
## Expertise Areas
|
|
52
|
+
|
|
53
|
+
### 1. Agent-to-Agent (A2A) Protocol
|
|
54
|
+
|
|
55
|
+
**Protocol Overview:**
|
|
56
|
+
- Universal communication standard for agent interoperability
|
|
57
|
+
- Donated by Google Cloud to Linux Foundation (June 2025)
|
|
58
|
+
- Support from 50+ technology partners (Box, Deloitte, Elastic, Salesforce, ServiceNow, UiPath, UKG)
|
|
59
|
+
- Framework-agnostic (ADK, LangGraph, CrewAI, LangChain)
|
|
60
|
+
- Standardized agent discovery and collaboration
|
|
61
|
+
|
|
62
|
+
**Core Components:**
|
|
63
|
+
- **Agent Cards**: Define agent capabilities, skills, and authentication
|
|
64
|
+
- **Message Protocol**: Standardized inter-agent communication
|
|
65
|
+
- **Task Management**: Asynchronous task execution and monitoring
|
|
66
|
+
- **Authentication**: Enterprise-grade security (OAuth2, API keys, public)
|
|
67
|
+
- **Capabilities**: Streaming, push notifications, multimodal I/O
|
|
68
|
+
|
|
69
|
+
**A2A Operations:**
|
|
70
|
+
1. Send messages - Initiate tasks with user messages
|
|
71
|
+
2. Retrieve tasks - Check status and artifacts
|
|
72
|
+
3. Cancel tasks - Stop running tasks
|
|
73
|
+
4. Get agent card - Retrieve capabilities and skills
|
|
74
|
+
|
|
75
|
+
### 2. Vertex AI Agent Builder
|
|
76
|
+
|
|
77
|
+
**Agent Builder Capabilities:**
|
|
78
|
+
- Visual agent design and configuration
|
|
79
|
+
- Pre-built agent templates and examples
|
|
80
|
+
- Integration with Google Cloud services
|
|
81
|
+
- Built-in tools (Search, Code Execution, APIs)
|
|
82
|
+
- Model Context Protocol (MCP) support
|
|
83
|
+
- Deployment to Agent Engine runtime
|
|
84
|
+
|
|
85
|
+
**Agent Engine Features:**
|
|
86
|
+
- Production-ready agent hosting
|
|
87
|
+
- Native A2A protocol support
|
|
88
|
+
- Automatic scaling and load balancing
|
|
89
|
+
- Secure agent discovery
|
|
90
|
+
- Task orchestration and monitoring
|
|
91
|
+
- Enterprise authentication and authorization
|
|
92
|
+
|
|
93
|
+
### 3. Agent Development Kit (ADK)
|
|
94
|
+
|
|
95
|
+
**ADK Framework:**
|
|
96
|
+
- Python-first development experience
|
|
97
|
+
- Build agents in <100 lines of code
|
|
98
|
+
- Deterministic guardrails and controls
|
|
99
|
+
- Sophisticated tool use patterns
|
|
100
|
+
- Dynamic orchestration capabilities
|
|
101
|
+
|
|
102
|
+
**Workflow Patterns:**
|
|
103
|
+
- **Sequential**: Linear agent pipelines
|
|
104
|
+
- **Parallel**: Concurrent agent execution
|
|
105
|
+
- **Loop**: Iterative agent workflows
|
|
106
|
+
- **LLM-driven routing**: Adaptive behavior based on context
|
|
107
|
+
|
|
108
|
+
**Tool Integration:**
|
|
109
|
+
- Pre-built tools (Search, Code Exec)
|
|
110
|
+
- Model Context Protocol (MCP) tools
|
|
111
|
+
- Third-party libraries (LangChain, LlamaIndex)
|
|
112
|
+
- Other agents as tools (LangGraph, CrewAI)
|
|
113
|
+
|
|
114
|
+
### 4. Multi-Agent Orchestration
|
|
115
|
+
|
|
116
|
+
**Framework Integration:**
|
|
117
|
+
- **LangGraph**: State machines and graph-based workflows
|
|
118
|
+
- **LangChain**: Tool composition and chains
|
|
119
|
+
- **CrewAI**: Role-based agent teams
|
|
120
|
+
- **AG2**: Autonomous agent collaboration
|
|
121
|
+
|
|
122
|
+
**Orchestration Strategies:**
|
|
123
|
+
- Hierarchical delegation (supervisor agents)
|
|
124
|
+
- Peer-to-peer collaboration
|
|
125
|
+
- Pipeline processing (sequential agents)
|
|
126
|
+
- Dynamic routing (LLM-based decisions)
|
|
127
|
+
- Event-driven coordination
|
|
128
|
+
|
|
129
|
+
## Implementation Patterns
|
|
130
|
+
|
|
131
|
+
### 1. Agent Card Definition
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from a2a import AgentCard, AgentCapabilities, AgentAuthentication, AgentSkill
|
|
135
|
+
|
|
136
|
+
# Define agent skill
|
|
137
|
+
skill = AgentSkill(
|
|
138
|
+
name="customer_support",
|
|
139
|
+
description="Handle customer inquiries and support requests",
|
|
140
|
+
inputModes=["text", "application/json"],
|
|
141
|
+
outputModes=["text", "application/json"],
|
|
142
|
+
parameters={
|
|
143
|
+
"type": "object",
|
|
144
|
+
"properties": {
|
|
145
|
+
"query": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"description": "Customer question or issue"
|
|
148
|
+
},
|
|
149
|
+
"priority": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"enum": ["low", "medium", "high"],
|
|
152
|
+
"description": "Priority level"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"required": ["query"]
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Create agent card
|
|
160
|
+
agent_card = AgentCard(
|
|
161
|
+
name="Customer Support Agent",
|
|
162
|
+
description="AI agent specialized in customer support and issue resolution",
|
|
163
|
+
url="https://your-agent-endpoint.run.app/",
|
|
164
|
+
version="1.0.0",
|
|
165
|
+
defaultInputModes=["text", "application/json"],
|
|
166
|
+
defaultOutputModes=["text", "application/json"],
|
|
167
|
+
capabilities=AgentCapabilities(
|
|
168
|
+
streaming=True,
|
|
169
|
+
pushNotifications=False,
|
|
170
|
+
stateManagement=True
|
|
171
|
+
),
|
|
172
|
+
skills=[skill],
|
|
173
|
+
authentication=AgentAuthentication(
|
|
174
|
+
schemes=["bearer", "oauth2"] # Enterprise authentication
|
|
175
|
+
),
|
|
176
|
+
metadata={
|
|
177
|
+
"author": "Your Organization",
|
|
178
|
+
"tags": ["customer-service", "support", "chat"],
|
|
179
|
+
"documentation_url": "https://docs.yourorg.com/agents/customer-support"
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 2. A2A Python SDK Integration
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from a2a import A2AClient, ClientFactory, Task, Message
|
|
188
|
+
from google.auth import default
|
|
189
|
+
import asyncio
|
|
190
|
+
|
|
191
|
+
class A2AAgentClient:
|
|
192
|
+
"""Production-ready A2A client with error handling and retry logic"""
|
|
193
|
+
|
|
194
|
+
def __init__(self, agent_url: str, project_id: str, location: str = "us-central1"):
|
|
195
|
+
self.agent_url = agent_url
|
|
196
|
+
self.project_id = project_id
|
|
197
|
+
self.location = location
|
|
198
|
+
self.client = None
|
|
199
|
+
|
|
200
|
+
async def initialize(self):
|
|
201
|
+
"""Initialize A2A client with Google Cloud authentication"""
|
|
202
|
+
try:
|
|
203
|
+
# Get default credentials
|
|
204
|
+
credentials, _ = default()
|
|
205
|
+
|
|
206
|
+
# Create A2A client using ClientFactory
|
|
207
|
+
self.client = await ClientFactory.create_client(
|
|
208
|
+
agent_url=self.agent_url,
|
|
209
|
+
credentials=credentials
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Retrieve and validate agent card
|
|
213
|
+
agent_card = await self.client.get_agent_card()
|
|
214
|
+
print(f"Connected to agent: {agent_card.name} v{agent_card.version}")
|
|
215
|
+
|
|
216
|
+
return agent_card
|
|
217
|
+
|
|
218
|
+
except Exception as e:
|
|
219
|
+
print(f"Failed to initialize A2A client: {e}")
|
|
220
|
+
raise
|
|
221
|
+
|
|
222
|
+
async def send_task(self, user_message: str, skill_name: str = None) -> Task:
|
|
223
|
+
"""Send task to agent with optional skill specification"""
|
|
224
|
+
if not self.client:
|
|
225
|
+
raise RuntimeError("Client not initialized. Call initialize() first.")
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
# Create message
|
|
229
|
+
message = Message(
|
|
230
|
+
role="user",
|
|
231
|
+
content=[{
|
|
232
|
+
"type": "text",
|
|
233
|
+
"text": user_message
|
|
234
|
+
}]
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Send task
|
|
238
|
+
task = await self.client.send_task(
|
|
239
|
+
messages=[message],
|
|
240
|
+
skill_name=skill_name, # Optional: target specific skill
|
|
241
|
+
stream=False
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
return task
|
|
245
|
+
|
|
246
|
+
except Exception as e:
|
|
247
|
+
print(f"Failed to send task: {e}")
|
|
248
|
+
raise
|
|
249
|
+
|
|
250
|
+
async def stream_task(self, user_message: str, skill_name: str = None):
|
|
251
|
+
"""Stream task responses for real-time updates"""
|
|
252
|
+
if not self.client:
|
|
253
|
+
raise RuntimeError("Client not initialized. Call initialize() first.")
|
|
254
|
+
|
|
255
|
+
try:
|
|
256
|
+
message = Message(
|
|
257
|
+
role="user",
|
|
258
|
+
content=[{
|
|
259
|
+
"type": "text",
|
|
260
|
+
"text": user_message
|
|
261
|
+
}]
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Stream responses
|
|
265
|
+
async for chunk in self.client.send_task_stream(
|
|
266
|
+
messages=[message],
|
|
267
|
+
skill_name=skill_name
|
|
268
|
+
):
|
|
269
|
+
if chunk.content:
|
|
270
|
+
for content_item in chunk.content:
|
|
271
|
+
if content_item.get("type") == "text":
|
|
272
|
+
yield content_item.get("text", "")
|
|
273
|
+
|
|
274
|
+
except Exception as e:
|
|
275
|
+
print(f"Failed to stream task: {e}")
|
|
276
|
+
raise
|
|
277
|
+
|
|
278
|
+
async def get_task_status(self, task_id: str) -> dict:
|
|
279
|
+
"""Retrieve task status and results"""
|
|
280
|
+
try:
|
|
281
|
+
task = await self.client.get_task(task_id)
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
"task_id": task.id,
|
|
285
|
+
"status": task.status, # pending, running, completed, failed
|
|
286
|
+
"artifacts": task.artifacts,
|
|
287
|
+
"messages": task.messages
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
except Exception as e:
|
|
291
|
+
print(f"Failed to get task status: {e}")
|
|
292
|
+
raise
|
|
293
|
+
|
|
294
|
+
async def cancel_task(self, task_id: str) -> bool:
|
|
295
|
+
"""Cancel a running task"""
|
|
296
|
+
try:
|
|
297
|
+
await self.client.cancel_task(task_id)
|
|
298
|
+
return True
|
|
299
|
+
except Exception as e:
|
|
300
|
+
print(f"Failed to cancel task: {e}")
|
|
301
|
+
return False
|
|
302
|
+
|
|
303
|
+
async def close(self):
|
|
304
|
+
"""Clean up client resources"""
|
|
305
|
+
if self.client:
|
|
306
|
+
await self.client.close()
|
|
307
|
+
|
|
308
|
+
# Usage example
|
|
309
|
+
async def main():
|
|
310
|
+
# Initialize client
|
|
311
|
+
client = A2AAgentClient(
|
|
312
|
+
agent_url="https://customer-support-agent.run.app/",
|
|
313
|
+
project_id="your-project-id",
|
|
314
|
+
location="us-central1"
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
try:
|
|
318
|
+
# Initialize and get agent card
|
|
319
|
+
agent_card = await client.initialize()
|
|
320
|
+
print(f"Available skills: {[skill.name for skill in agent_card.skills]}")
|
|
321
|
+
|
|
322
|
+
# Send synchronous task
|
|
323
|
+
task = await client.send_task(
|
|
324
|
+
"I need help with my order #12345",
|
|
325
|
+
skill_name="customer_support"
|
|
326
|
+
)
|
|
327
|
+
print(f"Task submitted: {task.id}")
|
|
328
|
+
|
|
329
|
+
# Stream task for real-time responses
|
|
330
|
+
print("\nStreaming response:")
|
|
331
|
+
async for text_chunk in client.stream_task(
|
|
332
|
+
"What is your refund policy?",
|
|
333
|
+
skill_name="customer_support"
|
|
334
|
+
):
|
|
335
|
+
print(text_chunk, end="", flush=True)
|
|
336
|
+
|
|
337
|
+
# Check task status
|
|
338
|
+
status = await client.get_task_status(task.id)
|
|
339
|
+
print(f"\n\nTask status: {status['status']}")
|
|
340
|
+
|
|
341
|
+
finally:
|
|
342
|
+
await client.close()
|
|
343
|
+
|
|
344
|
+
if __name__ == "__main__":
|
|
345
|
+
asyncio.run(main())
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### 3. Vertex AI Agent Builder with ADK
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
from vertexai import Agent, Task, Tool
|
|
352
|
+
from vertexai.agents import adk
|
|
353
|
+
from google.cloud import aiplatform
|
|
354
|
+
import asyncio
|
|
355
|
+
|
|
356
|
+
# Initialize Vertex AI
|
|
357
|
+
aiplatform.init(
|
|
358
|
+
project="your-project-id",
|
|
359
|
+
location="us-central1"
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
class ResearchAgent:
|
|
363
|
+
"""ADK-based research agent with tool use"""
|
|
364
|
+
|
|
365
|
+
def __init__(self):
|
|
366
|
+
self.agent = None
|
|
367
|
+
self._setup_tools()
|
|
368
|
+
self._create_agent()
|
|
369
|
+
|
|
370
|
+
def _setup_tools(self):
|
|
371
|
+
"""Define agent tools"""
|
|
372
|
+
self.search_tool = Tool(
|
|
373
|
+
name="web_search",
|
|
374
|
+
description="Search the web for information",
|
|
375
|
+
parameters={
|
|
376
|
+
"type": "object",
|
|
377
|
+
"properties": {
|
|
378
|
+
"query": {
|
|
379
|
+
"type": "string",
|
|
380
|
+
"description": "Search query"
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
"required": ["query"]
|
|
384
|
+
},
|
|
385
|
+
function=self._web_search
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
self.summarize_tool = Tool(
|
|
389
|
+
name="summarize",
|
|
390
|
+
description="Summarize long text into key points",
|
|
391
|
+
parameters={
|
|
392
|
+
"type": "object",
|
|
393
|
+
"properties": {
|
|
394
|
+
"text": {
|
|
395
|
+
"type": "string",
|
|
396
|
+
"description": "Text to summarize"
|
|
397
|
+
},
|
|
398
|
+
"max_points": {
|
|
399
|
+
"type": "integer",
|
|
400
|
+
"description": "Maximum number of key points"
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
"required": ["text"]
|
|
404
|
+
},
|
|
405
|
+
function=self._summarize
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
async def _web_search(self, query: str) -> str:
|
|
409
|
+
"""Web search implementation"""
|
|
410
|
+
# Implement actual search logic here
|
|
411
|
+
return f"Search results for: {query}"
|
|
412
|
+
|
|
413
|
+
async def _summarize(self, text: str, max_points: int = 5) -> str:
|
|
414
|
+
"""Summarization implementation"""
|
|
415
|
+
# Implement actual summarization here
|
|
416
|
+
return f"Summary of text in {max_points} points"
|
|
417
|
+
|
|
418
|
+
def _create_agent(self):
|
|
419
|
+
"""Create ADK agent with tools"""
|
|
420
|
+
self.agent = Agent(
|
|
421
|
+
name="Research Agent",
|
|
422
|
+
model="gemini-1.5-pro",
|
|
423
|
+
tools=[self.search_tool, self.summarize_tool],
|
|
424
|
+
instructions="""You are a research assistant that helps users find and
|
|
425
|
+
summarize information. Use web search to find relevant information,
|
|
426
|
+
then summarize the findings into clear, actionable insights.""",
|
|
427
|
+
safety_settings={
|
|
428
|
+
"HARM_CATEGORY_HARASSMENT": "BLOCK_MEDIUM_AND_ABOVE",
|
|
429
|
+
"HARM_CATEGORY_HATE_SPEECH": "BLOCK_MEDIUM_AND_ABOVE",
|
|
430
|
+
"HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_MEDIUM_AND_ABOVE",
|
|
431
|
+
"HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_MEDIUM_AND_ABOVE"
|
|
432
|
+
}
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
async def execute_task(self, query: str) -> str:
|
|
436
|
+
"""Execute research task"""
|
|
437
|
+
task = Task(
|
|
438
|
+
agent=self.agent,
|
|
439
|
+
user_message=query
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
result = await task.execute()
|
|
443
|
+
return result.content
|
|
444
|
+
|
|
445
|
+
# Multi-agent orchestration with ADK
|
|
446
|
+
class MultiAgentOrchestrator:
|
|
447
|
+
"""Orchestrate multiple agents with ADK workflow patterns"""
|
|
448
|
+
|
|
449
|
+
def __init__(self):
|
|
450
|
+
self.research_agent = ResearchAgent()
|
|
451
|
+
self.analysis_agent = self._create_analysis_agent()
|
|
452
|
+
self.summary_agent = self._create_summary_agent()
|
|
453
|
+
|
|
454
|
+
def _create_analysis_agent(self) -> Agent:
|
|
455
|
+
"""Create analysis agent"""
|
|
456
|
+
return Agent(
|
|
457
|
+
name="Analysis Agent",
|
|
458
|
+
model="gemini-1.5-pro",
|
|
459
|
+
instructions="""Analyze research data and identify key trends,
|
|
460
|
+
patterns, and insights. Provide data-driven analysis."""
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
def _create_summary_agent(self) -> Agent:
|
|
464
|
+
"""Create summary agent"""
|
|
465
|
+
return Agent(
|
|
466
|
+
name="Summary Agent",
|
|
467
|
+
model="gemini-1.5-flash", # Faster model for summarization
|
|
468
|
+
instructions="""Create concise, executive-level summaries of
|
|
469
|
+
complex analyses. Focus on actionable insights."""
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
async def sequential_workflow(self, query: str) -> dict:
|
|
473
|
+
"""Sequential agent workflow: Research → Analyze → Summarize"""
|
|
474
|
+
|
|
475
|
+
# Step 1: Research
|
|
476
|
+
print("Step 1: Researching...")
|
|
477
|
+
research_results = await self.research_agent.execute_task(query)
|
|
478
|
+
|
|
479
|
+
# Step 2: Analyze
|
|
480
|
+
print("Step 2: Analyzing...")
|
|
481
|
+
analysis_task = Task(
|
|
482
|
+
agent=self.analysis_agent,
|
|
483
|
+
user_message=f"Analyze this research: {research_results}"
|
|
484
|
+
)
|
|
485
|
+
analysis_results = await analysis_task.execute()
|
|
486
|
+
|
|
487
|
+
# Step 3: Summarize
|
|
488
|
+
print("Step 3: Summarizing...")
|
|
489
|
+
summary_task = Task(
|
|
490
|
+
agent=self.summary_agent,
|
|
491
|
+
user_message=f"Summarize this analysis: {analysis_results.content}"
|
|
492
|
+
)
|
|
493
|
+
summary_results = await summary_task.execute()
|
|
494
|
+
|
|
495
|
+
return {
|
|
496
|
+
"research": research_results,
|
|
497
|
+
"analysis": analysis_results.content,
|
|
498
|
+
"summary": summary_results.content
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
async def parallel_workflow(self, queries: list[str]) -> list[str]:
|
|
502
|
+
"""Parallel agent execution for multiple queries"""
|
|
503
|
+
tasks = [
|
|
504
|
+
self.research_agent.execute_task(query)
|
|
505
|
+
for query in queries
|
|
506
|
+
]
|
|
507
|
+
|
|
508
|
+
results = await asyncio.gather(*tasks)
|
|
509
|
+
return results
|
|
510
|
+
|
|
511
|
+
# Usage
|
|
512
|
+
async def adk_example():
|
|
513
|
+
orchestrator = MultiAgentOrchestrator()
|
|
514
|
+
|
|
515
|
+
# Sequential workflow
|
|
516
|
+
result = await orchestrator.sequential_workflow(
|
|
517
|
+
"What are the latest trends in AI agent development?"
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
print(f"Final Summary: {result['summary']}")
|
|
521
|
+
|
|
522
|
+
# Parallel workflow
|
|
523
|
+
queries = [
|
|
524
|
+
"Vertex AI capabilities",
|
|
525
|
+
"A2A protocol overview",
|
|
526
|
+
"Multi-agent orchestration patterns"
|
|
527
|
+
]
|
|
528
|
+
|
|
529
|
+
results = await orchestrator.parallel_workflow(queries)
|
|
530
|
+
for query, result in zip(queries, results):
|
|
531
|
+
print(f"{query}: {result[:100]}...")
|
|
532
|
+
|
|
533
|
+
asyncio.run(adk_example())
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### 4. LangGraph Integration with A2A
|
|
537
|
+
|
|
538
|
+
```python
|
|
539
|
+
from langgraph.graph import StateGraph, END
|
|
540
|
+
from langgraph.prebuilt import ToolExecutor, ToolInvocation
|
|
541
|
+
from langchain_google_vertexai import ChatVertexAI
|
|
542
|
+
from typing import TypedDict, Annotated, List
|
|
543
|
+
import operator
|
|
544
|
+
|
|
545
|
+
# Define agent state
|
|
546
|
+
class AgentState(TypedDict):
|
|
547
|
+
messages: Annotated[List[dict], operator.add]
|
|
548
|
+
current_agent: str
|
|
549
|
+
task_result: str
|
|
550
|
+
|
|
551
|
+
class LangGraphA2AIntegration:
|
|
552
|
+
"""Integrate A2A agents with LangGraph workflows"""
|
|
553
|
+
|
|
554
|
+
def __init__(self):
|
|
555
|
+
self.llm = ChatVertexAI(model_name="gemini-1.5-pro")
|
|
556
|
+
self.graph = self._build_graph()
|
|
557
|
+
|
|
558
|
+
# A2A agent clients
|
|
559
|
+
self.research_agent = A2AAgentClient(
|
|
560
|
+
agent_url="https://research-agent.run.app/",
|
|
561
|
+
project_id="your-project-id"
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
self.analysis_agent = A2AAgentClient(
|
|
565
|
+
agent_url="https://analysis-agent.run.app/",
|
|
566
|
+
project_id="your-project-id"
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
async def call_research_agent(self, state: AgentState) -> AgentState:
|
|
570
|
+
"""Call A2A research agent"""
|
|
571
|
+
messages = state["messages"]
|
|
572
|
+
last_message = messages[-1]["content"]
|
|
573
|
+
|
|
574
|
+
# Initialize if needed
|
|
575
|
+
if not self.research_agent.client:
|
|
576
|
+
await self.research_agent.initialize()
|
|
577
|
+
|
|
578
|
+
# Send task to A2A agent
|
|
579
|
+
task = await self.research_agent.send_task(last_message)
|
|
580
|
+
|
|
581
|
+
# Wait for completion (or use streaming)
|
|
582
|
+
while True:
|
|
583
|
+
status = await self.research_agent.get_task_status(task.id)
|
|
584
|
+
if status["status"] == "completed":
|
|
585
|
+
result = status["messages"][-1]["content"]
|
|
586
|
+
break
|
|
587
|
+
elif status["status"] == "failed":
|
|
588
|
+
raise RuntimeError("Research task failed")
|
|
589
|
+
await asyncio.sleep(1)
|
|
590
|
+
|
|
591
|
+
return {
|
|
592
|
+
"messages": [{"role": "assistant", "content": result}],
|
|
593
|
+
"current_agent": "analysis",
|
|
594
|
+
"task_result": result
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
async def call_analysis_agent(self, state: AgentState) -> AgentState:
|
|
598
|
+
"""Call A2A analysis agent"""
|
|
599
|
+
research_result = state["task_result"]
|
|
600
|
+
|
|
601
|
+
if not self.analysis_agent.client:
|
|
602
|
+
await self.analysis_agent.initialize()
|
|
603
|
+
|
|
604
|
+
task = await self.analysis_agent.send_task(
|
|
605
|
+
f"Analyze this research: {research_result}"
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
# Wait for completion
|
|
609
|
+
while True:
|
|
610
|
+
status = await self.analysis_agent.get_task_status(task.id)
|
|
611
|
+
if status["status"] == "completed":
|
|
612
|
+
result = status["messages"][-1]["content"]
|
|
613
|
+
break
|
|
614
|
+
elif status["status"] == "failed":
|
|
615
|
+
raise RuntimeError("Analysis task failed")
|
|
616
|
+
await asyncio.sleep(1)
|
|
617
|
+
|
|
618
|
+
return {
|
|
619
|
+
"messages": [{"role": "assistant", "content": result}],
|
|
620
|
+
"current_agent": "end",
|
|
621
|
+
"task_result": result
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
def should_continue(self, state: AgentState) -> str:
|
|
625
|
+
"""Routing logic for agent selection"""
|
|
626
|
+
current_agent = state.get("current_agent", "research")
|
|
627
|
+
|
|
628
|
+
if current_agent == "research":
|
|
629
|
+
return "analysis"
|
|
630
|
+
elif current_agent == "analysis":
|
|
631
|
+
return "end"
|
|
632
|
+
else:
|
|
633
|
+
return "end"
|
|
634
|
+
|
|
635
|
+
def _build_graph(self) -> StateGraph:
|
|
636
|
+
"""Build LangGraph workflow with A2A agents"""
|
|
637
|
+
workflow = StateGraph(AgentState)
|
|
638
|
+
|
|
639
|
+
# Add agent nodes
|
|
640
|
+
workflow.add_node("research", self.call_research_agent)
|
|
641
|
+
workflow.add_node("analysis", self.call_analysis_agent)
|
|
642
|
+
|
|
643
|
+
# Define edges
|
|
644
|
+
workflow.set_entry_point("research")
|
|
645
|
+
|
|
646
|
+
workflow.add_conditional_edges(
|
|
647
|
+
"research",
|
|
648
|
+
self.should_continue,
|
|
649
|
+
{
|
|
650
|
+
"analysis": "analysis",
|
|
651
|
+
"end": END
|
|
652
|
+
}
|
|
653
|
+
)
|
|
654
|
+
|
|
655
|
+
workflow.add_conditional_edges(
|
|
656
|
+
"analysis",
|
|
657
|
+
self.should_continue,
|
|
658
|
+
{
|
|
659
|
+
"end": END
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
return workflow.compile()
|
|
664
|
+
|
|
665
|
+
async def run(self, query: str) -> str:
|
|
666
|
+
"""Execute LangGraph workflow with A2A agents"""
|
|
667
|
+
initial_state = {
|
|
668
|
+
"messages": [{"role": "user", "content": query}],
|
|
669
|
+
"current_agent": "research",
|
|
670
|
+
"task_result": ""
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
result = await self.graph.ainvoke(initial_state)
|
|
674
|
+
return result["task_result"]
|
|
675
|
+
|
|
676
|
+
# Usage
|
|
677
|
+
async def langgraph_a2a_example():
|
|
678
|
+
integration = LangGraphA2AIntegration()
|
|
679
|
+
|
|
680
|
+
result = await integration.run(
|
|
681
|
+
"Research and analyze the impact of AI agents on software development"
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
print(f"Final Result: {result}")
|
|
685
|
+
|
|
686
|
+
asyncio.run(langgraph_a2a_example())
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### 5. Production Deployment with Agent Engine
|
|
690
|
+
|
|
691
|
+
```python
|
|
692
|
+
from google.cloud import aiplatform
|
|
693
|
+
from vertexai.agents import Agent, deploy_agent
|
|
694
|
+
import json
|
|
695
|
+
|
|
696
|
+
class AgentEngineDeployment:
|
|
697
|
+
"""Deploy agents to Vertex AI Agent Engine with A2A support"""
|
|
698
|
+
|
|
699
|
+
def __init__(self, project_id: str, location: str = "us-central1"):
|
|
700
|
+
self.project_id = project_id
|
|
701
|
+
self.location = location
|
|
702
|
+
aiplatform.init(project=project_id, location=location)
|
|
703
|
+
|
|
704
|
+
def create_agent(self,
|
|
705
|
+
name: str,
|
|
706
|
+
description: str,
|
|
707
|
+
model: str = "gemini-1.5-pro",
|
|
708
|
+
tools: list = None,
|
|
709
|
+
instructions: str = None) -> Agent:
|
|
710
|
+
"""Create agent for deployment"""
|
|
711
|
+
|
|
712
|
+
agent = Agent(
|
|
713
|
+
name=name,
|
|
714
|
+
model=model,
|
|
715
|
+
tools=tools or [],
|
|
716
|
+
instructions=instructions or f"You are {name}.",
|
|
717
|
+
description=description
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
return agent
|
|
721
|
+
|
|
722
|
+
async def deploy_to_agent_engine(self,
|
|
723
|
+
agent: Agent,
|
|
724
|
+
enable_a2a: bool = True,
|
|
725
|
+
authentication_mode: str = "oauth2") -> dict:
|
|
726
|
+
"""Deploy agent to Agent Engine with A2A protocol"""
|
|
727
|
+
|
|
728
|
+
try:
|
|
729
|
+
# Deploy agent
|
|
730
|
+
deployment = await deploy_agent(
|
|
731
|
+
agent=agent,
|
|
732
|
+
reasoning_engine_config={
|
|
733
|
+
"enable_a2a_protocol": enable_a2a,
|
|
734
|
+
"authentication": {
|
|
735
|
+
"mode": authentication_mode, # public, bearer, oauth2
|
|
736
|
+
"oauth2_config": {
|
|
737
|
+
"issuer": f"https://accounts.google.com",
|
|
738
|
+
"audience": f"{self.project_id}"
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
"scaling": {
|
|
742
|
+
"min_instances": 1,
|
|
743
|
+
"max_instances": 10,
|
|
744
|
+
"target_cpu_utilization": 0.7
|
|
745
|
+
},
|
|
746
|
+
"monitoring": {
|
|
747
|
+
"enable_logging": True,
|
|
748
|
+
"enable_metrics": True,
|
|
749
|
+
"log_level": "INFO"
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
# Extract deployment details
|
|
755
|
+
resource_name = deployment.resource_name
|
|
756
|
+
endpoint_url = deployment.endpoint
|
|
757
|
+
|
|
758
|
+
# Generate agent card
|
|
759
|
+
agent_card = self._generate_agent_card(
|
|
760
|
+
agent=agent,
|
|
761
|
+
endpoint_url=endpoint_url,
|
|
762
|
+
authentication_mode=authentication_mode
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
return {
|
|
766
|
+
"resource_name": resource_name,
|
|
767
|
+
"endpoint_url": endpoint_url,
|
|
768
|
+
"agent_card": agent_card,
|
|
769
|
+
"status": "deployed"
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
except Exception as e:
|
|
773
|
+
print(f"Deployment failed: {e}")
|
|
774
|
+
raise
|
|
775
|
+
|
|
776
|
+
def _generate_agent_card(self,
|
|
777
|
+
agent: Agent,
|
|
778
|
+
endpoint_url: str,
|
|
779
|
+
authentication_mode: str) -> dict:
|
|
780
|
+
"""Generate A2A agent card for deployed agent"""
|
|
781
|
+
|
|
782
|
+
# Convert agent tools to A2A skills
|
|
783
|
+
skills = []
|
|
784
|
+
for tool in agent.tools or []:
|
|
785
|
+
skill = {
|
|
786
|
+
"name": tool.name,
|
|
787
|
+
"description": tool.description,
|
|
788
|
+
"inputModes": ["text", "application/json"],
|
|
789
|
+
"outputModes": ["text", "application/json"],
|
|
790
|
+
"parameters": tool.parameters
|
|
791
|
+
}
|
|
792
|
+
skills.append(skill)
|
|
793
|
+
|
|
794
|
+
agent_card = {
|
|
795
|
+
"name": agent.name,
|
|
796
|
+
"description": agent.description or "",
|
|
797
|
+
"url": endpoint_url,
|
|
798
|
+
"version": "1.0.0",
|
|
799
|
+
"defaultInputModes": ["text"],
|
|
800
|
+
"defaultOutputModes": ["text"],
|
|
801
|
+
"capabilities": {
|
|
802
|
+
"streaming": True,
|
|
803
|
+
"pushNotifications": False,
|
|
804
|
+
"stateManagement": True
|
|
805
|
+
},
|
|
806
|
+
"skills": skills,
|
|
807
|
+
"authentication": {
|
|
808
|
+
"schemes": [authentication_mode]
|
|
809
|
+
},
|
|
810
|
+
"metadata": {
|
|
811
|
+
"framework": "Vertex AI Agent Engine",
|
|
812
|
+
"model": agent.model,
|
|
813
|
+
"project": self.project_id,
|
|
814
|
+
"location": self.location
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
return agent_card
|
|
819
|
+
|
|
820
|
+
async def update_agent(self, resource_name: str, agent: Agent) -> dict:
|
|
821
|
+
"""Update deployed agent"""
|
|
822
|
+
try:
|
|
823
|
+
updated_deployment = await deploy_agent(
|
|
824
|
+
agent=agent,
|
|
825
|
+
reasoning_engine_resource_name=resource_name
|
|
826
|
+
)
|
|
827
|
+
|
|
828
|
+
return {
|
|
829
|
+
"resource_name": updated_deployment.resource_name,
|
|
830
|
+
"status": "updated"
|
|
831
|
+
}
|
|
832
|
+
except Exception as e:
|
|
833
|
+
print(f"Update failed: {e}")
|
|
834
|
+
raise
|
|
835
|
+
|
|
836
|
+
def get_agent_metrics(self, resource_name: str) -> dict:
|
|
837
|
+
"""Get agent metrics and monitoring data"""
|
|
838
|
+
# Use Cloud Monitoring API to fetch metrics
|
|
839
|
+
from google.cloud import monitoring_v3
|
|
840
|
+
|
|
841
|
+
client = monitoring_v3.MetricServiceClient()
|
|
842
|
+
project_name = f"projects/{self.project_id}"
|
|
843
|
+
|
|
844
|
+
# Define time interval (last 24 hours)
|
|
845
|
+
import time
|
|
846
|
+
now = time.time()
|
|
847
|
+
seconds = int(now)
|
|
848
|
+
nanos = int((now - seconds) * 10**9)
|
|
849
|
+
|
|
850
|
+
interval = monitoring_v3.TimeInterval({
|
|
851
|
+
"end_time": {"seconds": seconds, "nanos": nanos},
|
|
852
|
+
"start_time": {"seconds": seconds - 86400, "nanos": nanos}
|
|
853
|
+
})
|
|
854
|
+
|
|
855
|
+
# Fetch request count metric
|
|
856
|
+
results = client.list_time_series(
|
|
857
|
+
request={
|
|
858
|
+
"name": project_name,
|
|
859
|
+
"filter": f'resource.type = "vertex_ai_agent_engine" AND resource.labels.resource_name = "{resource_name}"',
|
|
860
|
+
"interval": interval,
|
|
861
|
+
"view": monitoring_v3.ListTimeSeriesRequest.TimeSeriesView.FULL
|
|
862
|
+
}
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
metrics = {
|
|
866
|
+
"total_requests": 0,
|
|
867
|
+
"success_rate": 0.0,
|
|
868
|
+
"avg_latency_ms": 0.0,
|
|
869
|
+
"error_count": 0
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
for result in results:
|
|
873
|
+
# Process metrics
|
|
874
|
+
pass
|
|
875
|
+
|
|
876
|
+
return metrics
|
|
877
|
+
|
|
878
|
+
# Usage example
|
|
879
|
+
async def deployment_example():
|
|
880
|
+
deployer = AgentEngineDeployment(
|
|
881
|
+
project_id="your-project-id",
|
|
882
|
+
location="us-central1"
|
|
883
|
+
)
|
|
884
|
+
|
|
885
|
+
# Create agent
|
|
886
|
+
agent = deployer.create_agent(
|
|
887
|
+
name="Customer Support Agent",
|
|
888
|
+
description="AI agent for customer support and issue resolution",
|
|
889
|
+
model="gemini-1.5-pro",
|
|
890
|
+
instructions="""You are a helpful customer support agent.
|
|
891
|
+
Assist customers with their questions, provide accurate information,
|
|
892
|
+
and escalate complex issues when necessary."""
|
|
893
|
+
)
|
|
894
|
+
|
|
895
|
+
# Deploy with A2A protocol
|
|
896
|
+
deployment = await deployer.deploy_to_agent_engine(
|
|
897
|
+
agent=agent,
|
|
898
|
+
enable_a2a=True,
|
|
899
|
+
authentication_mode="oauth2"
|
|
900
|
+
)
|
|
901
|
+
|
|
902
|
+
print(f"Agent deployed: {deployment['endpoint_url']}")
|
|
903
|
+
print(f"Agent card: {json.dumps(deployment['agent_card'], indent=2)}")
|
|
904
|
+
|
|
905
|
+
# Get metrics
|
|
906
|
+
metrics = deployer.get_agent_metrics(deployment['resource_name'])
|
|
907
|
+
print(f"Metrics: {metrics}")
|
|
908
|
+
|
|
909
|
+
asyncio.run(deployment_example())
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
## Production Best Practices
|
|
913
|
+
|
|
914
|
+
### 1. Error Handling and Retry Logic
|
|
915
|
+
|
|
916
|
+
```python
|
|
917
|
+
import asyncio
|
|
918
|
+
from typing import Optional, Callable
|
|
919
|
+
import logging
|
|
920
|
+
|
|
921
|
+
logger = logging.getLogger(__name__)
|
|
922
|
+
|
|
923
|
+
class A2AErrorHandler:
|
|
924
|
+
"""Production error handling for A2A agents"""
|
|
925
|
+
|
|
926
|
+
def __init__(self, max_retries: int = 3, base_delay: float = 1.0):
|
|
927
|
+
self.max_retries = max_retries
|
|
928
|
+
self.base_delay = base_delay
|
|
929
|
+
|
|
930
|
+
async def with_retry(self,
|
|
931
|
+
func: Callable,
|
|
932
|
+
*args,
|
|
933
|
+
**kwargs) -> Optional[any]:
|
|
934
|
+
"""Execute function with exponential backoff retry"""
|
|
935
|
+
|
|
936
|
+
last_exception = None
|
|
937
|
+
|
|
938
|
+
for attempt in range(self.max_retries):
|
|
939
|
+
try:
|
|
940
|
+
return await func(*args, **kwargs)
|
|
941
|
+
|
|
942
|
+
except asyncio.TimeoutError as e:
|
|
943
|
+
last_exception = e
|
|
944
|
+
logger.warning(f"Timeout on attempt {attempt + 1}/{self.max_retries}")
|
|
945
|
+
|
|
946
|
+
except ConnectionError as e:
|
|
947
|
+
last_exception = e
|
|
948
|
+
logger.warning(f"Connection error on attempt {attempt + 1}/{self.max_retries}")
|
|
949
|
+
|
|
950
|
+
except Exception as e:
|
|
951
|
+
last_exception = e
|
|
952
|
+
logger.error(f"Unexpected error: {e}")
|
|
953
|
+
|
|
954
|
+
# Don't retry on certain errors
|
|
955
|
+
if "authentication" in str(e).lower():
|
|
956
|
+
raise
|
|
957
|
+
if "rate limit" in str(e).lower():
|
|
958
|
+
# Wait longer for rate limits
|
|
959
|
+
await asyncio.sleep(60)
|
|
960
|
+
continue
|
|
961
|
+
|
|
962
|
+
# Exponential backoff
|
|
963
|
+
if attempt < self.max_retries - 1:
|
|
964
|
+
delay = self.base_delay * (2 ** attempt)
|
|
965
|
+
logger.info(f"Retrying in {delay} seconds...")
|
|
966
|
+
await asyncio.sleep(delay)
|
|
967
|
+
|
|
968
|
+
logger.error(f"All {self.max_retries} attempts failed")
|
|
969
|
+
raise last_exception
|
|
970
|
+
|
|
971
|
+
async def with_timeout(self,
|
|
972
|
+
func: Callable,
|
|
973
|
+
timeout_seconds: float,
|
|
974
|
+
*args,
|
|
975
|
+
**kwargs) -> any:
|
|
976
|
+
"""Execute function with timeout"""
|
|
977
|
+
try:
|
|
978
|
+
return await asyncio.wait_for(
|
|
979
|
+
func(*args, **kwargs),
|
|
980
|
+
timeout=timeout_seconds
|
|
981
|
+
)
|
|
982
|
+
except asyncio.TimeoutError:
|
|
983
|
+
logger.error(f"Operation timed out after {timeout_seconds}s")
|
|
984
|
+
raise
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
### 2. Security and Authentication
|
|
988
|
+
|
|
989
|
+
```python
|
|
990
|
+
from google.oauth2 import service_account
|
|
991
|
+
from google.auth.transport.requests import Request
|
|
992
|
+
import json
|
|
993
|
+
|
|
994
|
+
class A2ASecurityManager:
|
|
995
|
+
"""Manage authentication and security for A2A agents"""
|
|
996
|
+
|
|
997
|
+
def __init__(self, credentials_path: str = None):
|
|
998
|
+
self.credentials_path = credentials_path
|
|
999
|
+
self.credentials = None
|
|
1000
|
+
self.token = None
|
|
1001
|
+
|
|
1002
|
+
def load_credentials(self):
|
|
1003
|
+
"""Load service account credentials"""
|
|
1004
|
+
if self.credentials_path:
|
|
1005
|
+
self.credentials = service_account.Credentials.from_service_account_file(
|
|
1006
|
+
self.credentials_path,
|
|
1007
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
1008
|
+
)
|
|
1009
|
+
else:
|
|
1010
|
+
# Use default credentials
|
|
1011
|
+
from google.auth import default
|
|
1012
|
+
self.credentials, _ = default()
|
|
1013
|
+
|
|
1014
|
+
def get_access_token(self) -> str:
|
|
1015
|
+
"""Get fresh OAuth2 access token"""
|
|
1016
|
+
if not self.credentials:
|
|
1017
|
+
self.load_credentials()
|
|
1018
|
+
|
|
1019
|
+
# Refresh token if expired
|
|
1020
|
+
if not self.credentials.valid:
|
|
1021
|
+
self.credentials.refresh(Request())
|
|
1022
|
+
|
|
1023
|
+
return self.credentials.token
|
|
1024
|
+
|
|
1025
|
+
def create_auth_header(self) -> dict:
|
|
1026
|
+
"""Create authentication header for A2A requests"""
|
|
1027
|
+
token = self.get_access_token()
|
|
1028
|
+
return {
|
|
1029
|
+
"Authorization": f"Bearer {token}",
|
|
1030
|
+
"Content-Type": "application/json"
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
def validate_agent_card(self, agent_card: dict) -> bool:
|
|
1034
|
+
"""Validate agent card structure and security"""
|
|
1035
|
+
required_fields = ["name", "url", "version", "authentication"]
|
|
1036
|
+
|
|
1037
|
+
for field in required_fields:
|
|
1038
|
+
if field not in agent_card:
|
|
1039
|
+
logger.error(f"Missing required field: {field}")
|
|
1040
|
+
return False
|
|
1041
|
+
|
|
1042
|
+
# Validate HTTPS endpoint
|
|
1043
|
+
if not agent_card["url"].startswith("https://"):
|
|
1044
|
+
logger.error("Agent URL must use HTTPS")
|
|
1045
|
+
return False
|
|
1046
|
+
|
|
1047
|
+
# Validate authentication schemes
|
|
1048
|
+
auth_schemes = agent_card["authentication"].get("schemes", [])
|
|
1049
|
+
if "public" in auth_schemes:
|
|
1050
|
+
logger.warning("Agent uses public authentication (no security)")
|
|
1051
|
+
|
|
1052
|
+
return True
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
### 3. Monitoring and Observability
|
|
1056
|
+
|
|
1057
|
+
```python
|
|
1058
|
+
from dataclasses import dataclass, field
|
|
1059
|
+
from datetime import datetime
|
|
1060
|
+
from typing import List, Dict
|
|
1061
|
+
import json
|
|
1062
|
+
|
|
1063
|
+
@dataclass
|
|
1064
|
+
class AgentMetrics:
|
|
1065
|
+
"""Track agent performance metrics"""
|
|
1066
|
+
agent_name: str
|
|
1067
|
+
total_requests: int = 0
|
|
1068
|
+
successful_requests: int = 0
|
|
1069
|
+
failed_requests: int = 0
|
|
1070
|
+
total_latency_ms: float = 0.0
|
|
1071
|
+
request_history: List[Dict] = field(default_factory=list)
|
|
1072
|
+
|
|
1073
|
+
@property
|
|
1074
|
+
def success_rate(self) -> float:
|
|
1075
|
+
if self.total_requests == 0:
|
|
1076
|
+
return 0.0
|
|
1077
|
+
return (self.successful_requests / self.total_requests) * 100
|
|
1078
|
+
|
|
1079
|
+
@property
|
|
1080
|
+
def avg_latency_ms(self) -> float:
|
|
1081
|
+
if self.successful_requests == 0:
|
|
1082
|
+
return 0.0
|
|
1083
|
+
return self.total_latency_ms / self.successful_requests
|
|
1084
|
+
|
|
1085
|
+
def record_request(self, success: bool, latency_ms: float, error: str = None):
|
|
1086
|
+
"""Record request metrics"""
|
|
1087
|
+
self.total_requests += 1
|
|
1088
|
+
|
|
1089
|
+
if success:
|
|
1090
|
+
self.successful_requests += 1
|
|
1091
|
+
self.total_latency_ms += latency_ms
|
|
1092
|
+
else:
|
|
1093
|
+
self.failed_requests += 1
|
|
1094
|
+
|
|
1095
|
+
self.request_history.append({
|
|
1096
|
+
"timestamp": datetime.now().isoformat(),
|
|
1097
|
+
"success": success,
|
|
1098
|
+
"latency_ms": latency_ms,
|
|
1099
|
+
"error": error
|
|
1100
|
+
})
|
|
1101
|
+
|
|
1102
|
+
# Keep only last 1000 requests
|
|
1103
|
+
if len(self.request_history) > 1000:
|
|
1104
|
+
self.request_history = self.request_history[-1000:]
|
|
1105
|
+
|
|
1106
|
+
def to_dict(self) -> dict:
|
|
1107
|
+
return {
|
|
1108
|
+
"agent_name": self.agent_name,
|
|
1109
|
+
"total_requests": self.total_requests,
|
|
1110
|
+
"successful_requests": self.successful_requests,
|
|
1111
|
+
"failed_requests": self.failed_requests,
|
|
1112
|
+
"success_rate": self.success_rate,
|
|
1113
|
+
"avg_latency_ms": self.avg_latency_ms
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
class A2AMonitoringService:
|
|
1117
|
+
"""Centralized monitoring for A2A agents"""
|
|
1118
|
+
|
|
1119
|
+
def __init__(self):
|
|
1120
|
+
self.agent_metrics: Dict[str, AgentMetrics] = {}
|
|
1121
|
+
self.logger = logging.getLogger("a2a_monitoring")
|
|
1122
|
+
|
|
1123
|
+
def get_or_create_metrics(self, agent_name: str) -> AgentMetrics:
|
|
1124
|
+
"""Get or create metrics for agent"""
|
|
1125
|
+
if agent_name not in self.agent_metrics:
|
|
1126
|
+
self.agent_metrics[agent_name] = AgentMetrics(agent_name=agent_name)
|
|
1127
|
+
return self.agent_metrics[agent_name]
|
|
1128
|
+
|
|
1129
|
+
async def track_request(self,
|
|
1130
|
+
agent_name: str,
|
|
1131
|
+
request_func: Callable,
|
|
1132
|
+
*args,
|
|
1133
|
+
**kwargs) -> any:
|
|
1134
|
+
"""Track request execution and metrics"""
|
|
1135
|
+
metrics = self.get_or_create_metrics(agent_name)
|
|
1136
|
+
|
|
1137
|
+
start_time = asyncio.get_event_loop().time()
|
|
1138
|
+
error = None
|
|
1139
|
+
|
|
1140
|
+
try:
|
|
1141
|
+
result = await request_func(*args, **kwargs)
|
|
1142
|
+
success = True
|
|
1143
|
+
return result
|
|
1144
|
+
|
|
1145
|
+
except Exception as e:
|
|
1146
|
+
success = False
|
|
1147
|
+
error = str(e)
|
|
1148
|
+
raise
|
|
1149
|
+
|
|
1150
|
+
finally:
|
|
1151
|
+
end_time = asyncio.get_event_loop().time()
|
|
1152
|
+
latency_ms = (end_time - start_time) * 1000
|
|
1153
|
+
|
|
1154
|
+
metrics.record_request(success, latency_ms, error)
|
|
1155
|
+
|
|
1156
|
+
# Log metrics periodically
|
|
1157
|
+
if metrics.total_requests % 100 == 0:
|
|
1158
|
+
self.logger.info(
|
|
1159
|
+
f"Agent {agent_name}: {metrics.total_requests} requests, "
|
|
1160
|
+
f"{metrics.success_rate:.1f}% success rate, "
|
|
1161
|
+
f"{metrics.avg_latency_ms:.1f}ms avg latency"
|
|
1162
|
+
)
|
|
1163
|
+
|
|
1164
|
+
def get_all_metrics(self) -> Dict[str, dict]:
|
|
1165
|
+
"""Get metrics for all agents"""
|
|
1166
|
+
return {
|
|
1167
|
+
name: metrics.to_dict()
|
|
1168
|
+
for name, metrics in self.agent_metrics.items()
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
def export_metrics(self, filepath: str):
|
|
1172
|
+
"""Export metrics to file"""
|
|
1173
|
+
with open(filepath, 'w') as f:
|
|
1174
|
+
json.dump(self.get_all_metrics(), f, indent=2)
|
|
1175
|
+
```
|
|
1176
|
+
|
|
1177
|
+
### 4. Cost Optimization
|
|
1178
|
+
|
|
1179
|
+
```python
|
|
1180
|
+
class A2ACostOptimizer:
|
|
1181
|
+
"""Optimize costs for A2A agent deployments"""
|
|
1182
|
+
|
|
1183
|
+
def __init__(self):
|
|
1184
|
+
# Pricing per 1M tokens (approximate, check current pricing)
|
|
1185
|
+
self.pricing = {
|
|
1186
|
+
"gemini-1.5-pro": {
|
|
1187
|
+
"input": 3.50,
|
|
1188
|
+
"output": 10.50
|
|
1189
|
+
},
|
|
1190
|
+
"gemini-1.5-flash": {
|
|
1191
|
+
"input": 0.075,
|
|
1192
|
+
"output": 0.30
|
|
1193
|
+
},
|
|
1194
|
+
"gemini-1.0-pro": {
|
|
1195
|
+
"input": 0.50,
|
|
1196
|
+
"output": 1.50
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
self.cost_tracking = {}
|
|
1201
|
+
|
|
1202
|
+
def estimate_cost(self,
|
|
1203
|
+
model: str,
|
|
1204
|
+
input_tokens: int,
|
|
1205
|
+
output_tokens: int) -> float:
|
|
1206
|
+
"""Estimate cost for agent request"""
|
|
1207
|
+
if model not in self.pricing:
|
|
1208
|
+
return 0.0
|
|
1209
|
+
|
|
1210
|
+
input_cost = (input_tokens / 1_000_000) * self.pricing[model]["input"]
|
|
1211
|
+
output_cost = (output_tokens / 1_000_000) * self.pricing[model]["output"]
|
|
1212
|
+
|
|
1213
|
+
return input_cost + output_cost
|
|
1214
|
+
|
|
1215
|
+
def recommend_model(self, task_complexity: str) -> str:
|
|
1216
|
+
"""Recommend cost-effective model based on task"""
|
|
1217
|
+
recommendations = {
|
|
1218
|
+
"simple": "gemini-1.5-flash", # Fast, cheap
|
|
1219
|
+
"medium": "gemini-1.0-pro", # Balanced
|
|
1220
|
+
"complex": "gemini-1.5-pro" # Best quality
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
return recommendations.get(task_complexity, "gemini-1.5-pro")
|
|
1224
|
+
|
|
1225
|
+
def optimize_agent_card(self, agent_card: dict) -> dict:
|
|
1226
|
+
"""Optimize agent card for cost efficiency"""
|
|
1227
|
+
optimized = agent_card.copy()
|
|
1228
|
+
|
|
1229
|
+
# Disable streaming if not needed (reduces overhead)
|
|
1230
|
+
if not optimized.get("streaming_required", False):
|
|
1231
|
+
optimized["capabilities"]["streaming"] = False
|
|
1232
|
+
|
|
1233
|
+
# Use specific skills to reduce processing
|
|
1234
|
+
# Agents should only advertise skills they frequently use
|
|
1235
|
+
|
|
1236
|
+
return optimized
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
## Common Pitfalls
|
|
1240
|
+
|
|
1241
|
+
### ❌ Don't
|
|
1242
|
+
- Hardcode agent URLs or credentials
|
|
1243
|
+
- Ignore A2A protocol version compatibility
|
|
1244
|
+
- Skip agent card validation
|
|
1245
|
+
- Use synchronous calls in production
|
|
1246
|
+
- Deploy without authentication
|
|
1247
|
+
- Ignore rate limits and quotas
|
|
1248
|
+
- Skip error handling for network issues
|
|
1249
|
+
- Use verbose logging in production
|
|
1250
|
+
- Neglect agent versioning
|
|
1251
|
+
- Deploy without monitoring
|
|
1252
|
+
|
|
1253
|
+
### ✅ Do
|
|
1254
|
+
- Use environment variables for configuration
|
|
1255
|
+
- Validate agent cards before deployment
|
|
1256
|
+
- Implement async/await patterns
|
|
1257
|
+
- Use OAuth2 or bearer tokens for security
|
|
1258
|
+
- Monitor rate limits and costs
|
|
1259
|
+
- Implement comprehensive error handling
|
|
1260
|
+
- Use structured logging
|
|
1261
|
+
- Version agents properly (semantic versioning)
|
|
1262
|
+
- Set up monitoring and alerting
|
|
1263
|
+
- Test agent integration thoroughly
|
|
1264
|
+
- Cache agent cards to reduce lookups
|
|
1265
|
+
- Use appropriate models for task complexity
|
|
1266
|
+
- Implement circuit breakers for resilience
|
|
1267
|
+
- Document agent capabilities clearly
|
|
1268
|
+
|
|
1269
|
+
## Testing Strategies
|
|
1270
|
+
|
|
1271
|
+
### Unit Tests
|
|
1272
|
+
|
|
1273
|
+
```python
|
|
1274
|
+
import pytest
|
|
1275
|
+
from unittest.mock import AsyncMock, patch, MagicMock
|
|
1276
|
+
|
|
1277
|
+
@pytest.mark.asyncio
|
|
1278
|
+
async def test_a2a_client_initialization():
|
|
1279
|
+
"""Test A2A client initialization"""
|
|
1280
|
+
with patch('a2a.ClientFactory.create_client') as mock_client:
|
|
1281
|
+
mock_client.return_value = AsyncMock()
|
|
1282
|
+
|
|
1283
|
+
client = A2AAgentClient(
|
|
1284
|
+
agent_url="https://test-agent.run.app/",
|
|
1285
|
+
project_id="test-project"
|
|
1286
|
+
)
|
|
1287
|
+
|
|
1288
|
+
await client.initialize()
|
|
1289
|
+
|
|
1290
|
+
assert client.client is not None
|
|
1291
|
+
mock_client.assert_called_once()
|
|
1292
|
+
|
|
1293
|
+
@pytest.mark.asyncio
|
|
1294
|
+
async def test_send_task_success():
|
|
1295
|
+
"""Test successful task submission"""
|
|
1296
|
+
client = A2AAgentClient(
|
|
1297
|
+
agent_url="https://test-agent.run.app/",
|
|
1298
|
+
project_id="test-project"
|
|
1299
|
+
)
|
|
1300
|
+
|
|
1301
|
+
# Mock client
|
|
1302
|
+
client.client = AsyncMock()
|
|
1303
|
+
client.client.send_task.return_value = MagicMock(id="task-123")
|
|
1304
|
+
|
|
1305
|
+
task = await client.send_task("Test message")
|
|
1306
|
+
|
|
1307
|
+
assert task.id == "task-123"
|
|
1308
|
+
client.client.send_task.assert_called_once()
|
|
1309
|
+
|
|
1310
|
+
@pytest.mark.asyncio
|
|
1311
|
+
async def test_error_handling():
|
|
1312
|
+
"""Test error handling in A2A client"""
|
|
1313
|
+
client = A2AAgentClient(
|
|
1314
|
+
agent_url="https://test-agent.run.app/",
|
|
1315
|
+
project_id="test-project"
|
|
1316
|
+
)
|
|
1317
|
+
|
|
1318
|
+
client.client = AsyncMock()
|
|
1319
|
+
client.client.send_task.side_effect = Exception("Network error")
|
|
1320
|
+
|
|
1321
|
+
with pytest.raises(Exception):
|
|
1322
|
+
await client.send_task("Test message")
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
### Integration Tests
|
|
1326
|
+
|
|
1327
|
+
```python
|
|
1328
|
+
@pytest.mark.integration
|
|
1329
|
+
@pytest.mark.asyncio
|
|
1330
|
+
async def test_real_a2a_agent():
|
|
1331
|
+
"""Test with real A2A agent (requires credentials)"""
|
|
1332
|
+
import os
|
|
1333
|
+
|
|
1334
|
+
if not os.getenv("GOOGLE_APPLICATION_CREDENTIALS"):
|
|
1335
|
+
pytest.skip("No credentials available")
|
|
1336
|
+
|
|
1337
|
+
client = A2AAgentClient(
|
|
1338
|
+
agent_url=os.getenv("TEST_AGENT_URL"),
|
|
1339
|
+
project_id=os.getenv("TEST_PROJECT_ID")
|
|
1340
|
+
)
|
|
1341
|
+
|
|
1342
|
+
await client.initialize()
|
|
1343
|
+
|
|
1344
|
+
task = await client.send_task("Hello, test message")
|
|
1345
|
+
assert task.id is not None
|
|
1346
|
+
|
|
1347
|
+
# Wait for completion
|
|
1348
|
+
status = await client.get_task_status(task.id)
|
|
1349
|
+
assert status["status"] in ["pending", "running", "completed"]
|
|
1350
|
+
|
|
1351
|
+
await client.close()
|
|
1352
|
+
|
|
1353
|
+
@pytest.mark.integration
|
|
1354
|
+
@pytest.mark.asyncio
|
|
1355
|
+
async def test_multi_agent_workflow():
|
|
1356
|
+
"""Test multi-agent orchestration"""
|
|
1357
|
+
orchestrator = MultiAgentOrchestrator()
|
|
1358
|
+
|
|
1359
|
+
result = await orchestrator.sequential_workflow(
|
|
1360
|
+
"Test query for integration testing"
|
|
1361
|
+
)
|
|
1362
|
+
|
|
1363
|
+
assert "research" in result
|
|
1364
|
+
assert "analysis" in result
|
|
1365
|
+
assert "summary" in result
|
|
1366
|
+
assert len(result["summary"]) > 0
|
|
1367
|
+
```
|
|
1368
|
+
|
|
1369
|
+
## Self-Verification Protocol
|
|
1370
|
+
|
|
1371
|
+
Before delivering any solution, verify:
|
|
1372
|
+
- [ ] Documentation from Context7 has been consulted
|
|
1373
|
+
- [ ] Code follows A2A protocol specification
|
|
1374
|
+
- [ ] Agent cards are properly structured
|
|
1375
|
+
- [ ] Authentication is implemented securely
|
|
1376
|
+
- [ ] Error handling covers network issues
|
|
1377
|
+
- [ ] Tests are written and passing (TDD)
|
|
1378
|
+
- [ ] Monitoring and logging are configured
|
|
1379
|
+
- [ ] Cost optimization is considered
|
|
1380
|
+
- [ ] Resource cleanup is handled properly
|
|
1381
|
+
- [ ] Multi-agent coordination is tested
|
|
1382
|
+
|
|
1383
|
+
## Resources
|
|
1384
|
+
|
|
1385
|
+
### Official Documentation
|
|
1386
|
+
- A2A Protocol: https://a2aprotocol.ai
|
|
1387
|
+
- Vertex AI Agent Builder: https://cloud.google.com/vertex-ai/docs/agent-builder
|
|
1388
|
+
- Agent Development Kit: https://google.github.io/adk-docs/
|
|
1389
|
+
- LangGraph: https://langchain-ai.github.io/langgraph/
|
|
1390
|
+
- Vertex AI SDK: https://cloud.google.com/vertex-ai/docs/python-sdk/use-vertex-ai-python-sdk
|
|
1391
|
+
|
|
1392
|
+
### Context7 Libraries
|
|
1393
|
+
- `/googleapis/google-cloud-python/vertexai` - Vertex AI Python SDK
|
|
1394
|
+
- `/websites/cloud_google/vertex-ai` - Official Vertex AI docs
|
|
1395
|
+
- `/google/generative-ai-python` - Gemini integration
|
|
1396
|
+
- `/websites/a2aprotocol` - A2A protocol specification
|
|
1397
|
+
- `/langgraph/langgraph` - LangGraph documentation
|
|
1398
|
+
- `/langchain/langchain` - LangChain integration
|
|
1399
|
+
|
|
1400
|
+
## When to Use This Agent
|
|
1401
|
+
|
|
1402
|
+
Invoke this agent for:
|
|
1403
|
+
- Implementing A2A protocol and agent cards
|
|
1404
|
+
- Building multi-agent systems with Vertex AI
|
|
1405
|
+
- Integrating agents across different frameworks
|
|
1406
|
+
- Deploying agents to Agent Engine
|
|
1407
|
+
- Orchestrating complex agent workflows
|
|
1408
|
+
- Securing agent-to-agent communication
|
|
1409
|
+
- Optimizing multi-agent performance
|
|
1410
|
+
- Monitoring agent collaboration
|
|
1411
|
+
- Migrating agents to A2A protocol
|
|
1412
|
+
- Troubleshooting agent integration issues
|
|
1413
|
+
|
|
1414
|
+
## Agent Capabilities
|
|
1415
|
+
|
|
1416
|
+
**This agent can:**
|
|
1417
|
+
- Design and implement A2A agent cards
|
|
1418
|
+
- Build multi-agent systems with ADK
|
|
1419
|
+
- Integrate LangGraph with A2A agents
|
|
1420
|
+
- Deploy agents to Vertex AI Agent Engine
|
|
1421
|
+
- Implement secure authentication patterns
|
|
1422
|
+
- Create agent orchestration workflows
|
|
1423
|
+
- Set up monitoring and cost tracking
|
|
1424
|
+
- Optimize agent performance
|
|
1425
|
+
- Debug agent communication issues
|
|
1426
|
+
- Migrate existing agents to A2A
|
|
1427
|
+
|
|
1428
|
+
**This agent will:**
|
|
1429
|
+
- Always query Context7 for latest A2A patterns
|
|
1430
|
+
- Follow Google Cloud best practices
|
|
1431
|
+
- Implement proper error handling
|
|
1432
|
+
- Consider security and authentication
|
|
1433
|
+
- Use async patterns for production
|
|
1434
|
+
- Include comprehensive monitoring
|
|
1435
|
+
- Optimize for cost and performance
|
|
1436
|
+
- Validate agent cards
|
|
1437
|
+
- Handle network issues gracefully
|
|
1438
|
+
- Document agent capabilities clearly
|
|
1439
|
+
|
|
1440
|
+
---
|
|
1441
|
+
|
|
1442
|
+
**Agent Version:** 1.0.0
|
|
1443
|
+
**Last Updated:** 2025-10-16
|
|
1444
|
+
**Specialization:** Google A2A Protocol & Multi-Agent Systems
|
|
1445
|
+
**Context7 Required:** Yes
|