From 492a0544b8810db546d70ff25f036b35347edb47 Mon Sep 17 00:00:00 2001 From: a2a-platform Date: Wed, 8 Jul 2026 12:32:02 +0000 Subject: [PATCH] deploy --- agent.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/agent.py b/agent.py index c06cc88..476d022 100644 --- a/agent.py +++ b/agent.py @@ -27,7 +27,7 @@ from a2a_pack import ( DEFAULT_BASE_URL = "https://blog.a2acloud.io" -OPERATIONS = json.loads("{\n \"create_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Create a blog post\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"create_blog_post\",\n \"parameters\": [],\n \"path\": \"/api/posts\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/BlogPostInput\"\n },\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"create_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Create a blog post\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"create_blog_post_comment\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Requires the shared a2a Cloud browser session cookie from the web login flow.\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"create_blog_post_comment\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/comments\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/BlogCommentInput\"\n },\n \"security\": [\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"create_blog_post_comment\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Create a comment\",\n \"tags\": [\n \"Comments\"\n ]\n },\n \"delete_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Delete a post by slug\",\n \"destructive\": true,\n \"method\": \"DELETE\",\n \"operation_id\": \"delete_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": null,\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"delete_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Delete a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"get_blog_health\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Check blog service health\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_health\",\n \"parameters\": [],\n \"path\": \"/api/healthz\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"get_blog_health\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Check blog service health\",\n \"tags\": [\n \"Health\"\n ]\n },\n \"get_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns a published post. Add `preview=1` to fetch drafts or future-dated posts; preview requests require either bearer auth or the `x-api-key` header.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n {\n \"description\": \"Set to `1` to bypass the public published-post filter. Requires authentication.\",\n \"in\": \"query\",\n \"name\": \"preview\",\n \"required\": false,\n \"schema\": {\n \"enum\": [\n \"1\"\n ],\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"get_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Get a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"get_blog_post_reactions\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns public like/dislike counts. If an a2a Cloud session cookie is present, `viewer_reaction` is populated.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_post_reactions\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/reaction\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"get_blog_post_reactions\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Get post reaction counts\",\n \"tags\": [\n \"Reactions\"\n ]\n },\n \"list_blog_post_comments\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"List comments for a post\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_blog_post_comments\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/comments\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"list_blog_post_comments\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"List comments for a post\",\n \"tags\": [\n \"Comments\"\n ]\n },\n \"list_blog_posts\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns published posts by default. `status=all` and `status=draft` include draft content and require either bearer auth or the `x-api-key` header.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_blog_posts\",\n \"parameters\": [\n {\n \"description\": \"Use `published` or omit the parameter for public published posts. `all` and `draft` require authentication.\",\n \"in\": \"query\",\n \"name\": \"status\",\n \"required\": false,\n \"schema\": {\n \"default\": \"published\",\n \"enum\": [\n \"published\",\n \"draft\",\n \"all\"\n ],\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"list_blog_posts\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"List posts\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"set_blog_post_reaction\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Creates, updates, or clears the authenticated viewer's like/dislike reaction.\",\n \"destructive\": true,\n \"method\": \"PUT\",\n \"operation_id\": \"set_blog_post_reaction\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/reaction\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/BlogReactionInput\"\n },\n \"security\": [\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"set_blog_post_reaction\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Set the viewer reaction\",\n \"tags\": [\n \"Reactions\"\n ]\n },\n \"upsert_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Upsert a post by slug\",\n \"destructive\": true,\n \"method\": \"PUT\",\n \"operation_id\": \"upsert_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/BlogPostInput\"\n },\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"upsert_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Upsert a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n }\n}") +OPERATIONS = json.loads("{\n \"create_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Create a blog post\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"create_blog_post\",\n \"parameters\": [],\n \"path\": \"/api/posts\",\n \"request_body\": {\n \"properties\": {\n \"author\": {\n \"default\": \"a2a cloud\",\n \"maxLength\": 120,\n \"type\": \"string\"\n },\n \"content\": {\n \"example\": \"# Shipping agents with receipts\\n\\nAgents need durable runtime boundaries.\",\n \"maxLength\": 120000,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"cover_image_url\": {\n \"format\": \"uri\",\n \"maxLength\": 500,\n \"type\": \"string\"\n },\n \"excerpt\": {\n \"default\": \"\",\n \"example\": \"Why agent infrastructure needs identity, authority, and proof.\",\n \"maxLength\": 420,\n \"type\": \"string\"\n },\n \"published_at\": {\n \"description\": \"Defaults to the current time for published posts and null for drafts.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"slug\": {\n \"description\": \"Optional on create. The path slug is used for upserts. Slugs are normalized to lowercase kebab-case.\",\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"type\": \"string\"\n },\n \"status\": {\n \"default\": \"published\",\n \"enum\": [\n \"draft\",\n \"published\"\n ],\n \"type\": \"string\"\n },\n \"tags\": {\n \"default\": [],\n \"items\": {\n \"type\": \"string\"\n },\n \"maxItems\": 12,\n \"type\": \"array\"\n },\n \"title\": {\n \"example\": \"Shipping agents with receipts\",\n \"maxLength\": 180,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"title\",\n \"content\"\n ],\n \"type\": \"object\"\n },\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"create_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Create a blog post\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"create_blog_post_comment\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Requires the shared a2a Cloud browser session cookie from the web login flow.\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"create_blog_post_comment\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/comments\",\n \"request_body\": {\n \"properties\": {\n \"body\": {\n \"example\": \"This cleared up the deployment flow.\",\n \"maxLength\": 4000,\n \"minLength\": 2,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"body\"\n ],\n \"type\": \"object\"\n },\n \"security\": [\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"create_blog_post_comment\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Create a comment\",\n \"tags\": [\n \"Comments\"\n ]\n },\n \"delete_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Delete a post by slug\",\n \"destructive\": true,\n \"method\": \"DELETE\",\n \"operation_id\": \"delete_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": null,\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"delete_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Delete a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"get_blog_health\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Check blog service health\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_health\",\n \"parameters\": [],\n \"path\": \"/api/healthz\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"get_blog_health\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Check blog service health\",\n \"tags\": [\n \"Health\"\n ]\n },\n \"get_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns a published post. Add `preview=1` to fetch drafts or future-dated posts; preview requests require either bearer auth or the `x-api-key` header.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n {\n \"description\": \"Set to `1` to bypass the public published-post filter. Requires authentication.\",\n \"in\": \"query\",\n \"name\": \"preview\",\n \"required\": false,\n \"schema\": {\n \"enum\": [\n \"1\"\n ],\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"get_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Get a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"get_blog_post_reactions\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns public like/dislike counts. If an a2a Cloud session cookie is present, `viewer_reaction` is populated.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"get_blog_post_reactions\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/reaction\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"get_blog_post_reactions\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Get post reaction counts\",\n \"tags\": [\n \"Reactions\"\n ]\n },\n \"list_blog_post_comments\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"List comments for a post\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_blog_post_comments\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/comments\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"list_blog_post_comments\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"List comments for a post\",\n \"tags\": [\n \"Comments\"\n ]\n },\n \"list_blog_posts\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Returns published posts by default. `status=all` and `status=draft` include draft content and require either bearer auth or the `x-api-key` header.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_blog_posts\",\n \"parameters\": [\n {\n \"description\": \"Use `published` or omit the parameter for public published posts. `all` and `draft` require authentication.\",\n \"in\": \"query\",\n \"name\": \"status\",\n \"required\": false,\n \"schema\": {\n \"default\": \"published\",\n \"enum\": [\n \"published\",\n \"draft\",\n \"all\"\n ],\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts\",\n \"request_body\": null,\n \"security\": [\n {},\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"list_blog_posts\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"List posts\",\n \"tags\": [\n \"Posts\"\n ]\n },\n \"set_blog_post_reaction\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Creates, updates, or clears the authenticated viewer's like/dislike reaction.\",\n \"destructive\": true,\n \"method\": \"PUT\",\n \"operation_id\": \"set_blog_post_reaction\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}/reaction\",\n \"request_body\": {\n \"properties\": {\n \"reaction\": {\n \"description\": \"Set to null to clear the viewer's reaction.\",\n \"oneOf\": [\n {\n \"enum\": [\n \"like\",\n \"dislike\"\n ],\n \"type\": \"string\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n },\n \"required\": [\n \"reaction\"\n ],\n \"type\": \"object\"\n },\n \"security\": [\n {\n \"a2aSession\": []\n }\n ],\n \"skill_name\": \"set_blog_post_reaction\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Set the viewer reaction\",\n \"tags\": [\n \"Reactions\"\n ]\n },\n \"upsert_blog_post\": {\n \"base_url\": \"https://blog.a2acloud.io\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Upsert a post by slug\",\n \"destructive\": true,\n \"method\": \"PUT\",\n \"operation_id\": \"upsert_blog_post\",\n \"parameters\": [\n {\n \"description\": \"Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.\",\n \"in\": \"path\",\n \"name\": \"slug\",\n \"required\": true,\n \"schema\": {\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/api/posts/{slug}\",\n \"request_body\": {\n \"properties\": {\n \"author\": {\n \"default\": \"a2a cloud\",\n \"maxLength\": 120,\n \"type\": \"string\"\n },\n \"content\": {\n \"example\": \"# Shipping agents with receipts\\n\\nAgents need durable runtime boundaries.\",\n \"maxLength\": 120000,\n \"minLength\": 1,\n \"type\": \"string\"\n },\n \"cover_image_url\": {\n \"format\": \"uri\",\n \"maxLength\": 500,\n \"type\": \"string\"\n },\n \"excerpt\": {\n \"default\": \"\",\n \"example\": \"Why agent infrastructure needs identity, authority, and proof.\",\n \"maxLength\": 420,\n \"type\": \"string\"\n },\n \"published_at\": {\n \"description\": \"Defaults to the current time for published posts and null for drafts.\",\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"slug\": {\n \"description\": \"Optional on create. The path slug is used for upserts. Slugs are normalized to lowercase kebab-case.\",\n \"example\": \"shipping-agents-with-receipts\",\n \"maxLength\": 120,\n \"type\": \"string\"\n },\n \"status\": {\n \"default\": \"published\",\n \"enum\": [\n \"draft\",\n \"published\"\n ],\n \"type\": \"string\"\n },\n \"tags\": {\n \"default\": [],\n \"items\": {\n \"type\": \"string\"\n },\n \"maxItems\": 12,\n \"type\": \"array\"\n },\n \"title\": {\n \"example\": \"Shipping agents with receipts\",\n \"maxLength\": 180,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"title\",\n \"content\"\n ],\n \"type\": \"object\"\n },\n \"security\": [\n {\n \"bearerAuth\": []\n },\n {\n \"apiKeyAuth\": []\n }\n ],\n \"skill_name\": \"upsert_blog_post\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://blog.a2acloud.io/openapi.json\",\n \"source_title\": \"a2a cloud blog API\",\n \"summary\": \"Upsert a post by slug\",\n \"tags\": [\n \"Posts\"\n ]\n }\n}") OPERATION_GROUPS = json.loads("[]") ROOT_SECURITY = json.loads("[]") SECURITY_SCHEMES = json.loads("{\n \"a2aSession\": {\n \"description\": \"Shared a2a Cloud browser session cookie.\",\n \"in\": \"cookie\",\n \"name\": \"a2a_session\",\n \"type\": \"apiKey\"\n },\n \"apiKeyAuth\": {\n \"description\": \"Use the configured `BLOG_API_KEY` value.\",\n \"in\": \"header\",\n \"name\": \"x-api-key\",\n \"type\": \"apiKey\"\n },\n \"bearerAuth\": {\n \"description\": \"Use `Authorization: Bearer $BLOG_API_KEY`.\",\n \"scheme\": \"bearer\",\n \"type\": \"http\"\n }\n}") @@ -158,7 +158,7 @@ class BlogOpenapiAgent(A2AAgent): description="POST /api/posts - Create a blog post", tags=('Posts',), timeout_seconds=120, - input_schema={'type': 'object', 'properties': {'body': {'$ref': '#/components/schemas/BlogPostInput', 'description': 'JSON request body.'}}, 'required': ['body'], 'additionalProperties': False}, + input_schema={'type': 'object', 'properties': {'body': {'type': 'object', 'required': ['title', 'content'], 'properties': {'slug': {'type': 'string', 'maxLength': 120, 'description': 'Optional on create. The path slug is used for upserts. Slugs are normalized to lowercase kebab-case.', 'example': 'shipping-agents-with-receipts'}, 'title': {'type': 'string', 'minLength': 1, 'maxLength': 180, 'example': 'Shipping agents with receipts'}, 'excerpt': {'type': 'string', 'maxLength': 420, 'default': '', 'example': 'Why agent infrastructure needs identity, authority, and proof.'}, 'content': {'type': 'string', 'minLength': 1, 'maxLength': 120000, 'example': '# Shipping agents with receipts\n\nAgents need durable runtime boundaries.'}, 'author': {'type': 'string', 'maxLength': 120, 'default': 'a2a cloud'}, 'status': {'type': 'string', 'enum': ['draft', 'published'], 'default': 'published'}, 'tags': {'type': 'array', 'maxItems': 12, 'items': {'type': 'string'}, 'default': []}, 'cover_image_url': {'type': 'string', 'format': 'uri', 'maxLength': 500}, 'published_at': {'type': 'string', 'format': 'date-time', 'description': 'Defaults to the current time for published posts and null for drafts.'}}, 'description': 'JSON request body.'}}, 'required': ['body'], 'additionalProperties': False}, ) async def create_blog_post( self, @@ -198,7 +198,7 @@ class BlogOpenapiAgent(A2AAgent): description="PUT /api/posts/{slug} - Upsert a post by slug", tags=('Posts',), timeout_seconds=120, - input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'$ref': '#/components/schemas/BlogPostInput', 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, + input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'type': 'object', 'required': ['title', 'content'], 'properties': {'slug': {'type': 'string', 'maxLength': 120, 'description': 'Optional on create. The path slug is used for upserts. Slugs are normalized to lowercase kebab-case.', 'example': 'shipping-agents-with-receipts'}, 'title': {'type': 'string', 'minLength': 1, 'maxLength': 180, 'example': 'Shipping agents with receipts'}, 'excerpt': {'type': 'string', 'maxLength': 420, 'default': '', 'example': 'Why agent infrastructure needs identity, authority, and proof.'}, 'content': {'type': 'string', 'minLength': 1, 'maxLength': 120000, 'example': '# Shipping agents with receipts\n\nAgents need durable runtime boundaries.'}, 'author': {'type': 'string', 'maxLength': 120, 'default': 'a2a cloud'}, 'status': {'type': 'string', 'enum': ['draft', 'published'], 'default': 'published'}, 'tags': {'type': 'array', 'maxItems': 12, 'items': {'type': 'string'}, 'default': []}, 'cover_image_url': {'type': 'string', 'format': 'uri', 'maxLength': 500}, 'published_at': {'type': 'string', 'format': 'date-time', 'description': 'Defaults to the current time for published posts and null for drafts.'}}, 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, ) async def upsert_blog_post( self, @@ -258,7 +258,7 @@ class BlogOpenapiAgent(A2AAgent): description="POST /api/posts/{slug}/comments - Create a comment", tags=('Comments',), timeout_seconds=120, - input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'$ref': '#/components/schemas/BlogCommentInput', 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, + input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'type': 'object', 'required': ['body'], 'properties': {'body': {'type': 'string', 'minLength': 2, 'maxLength': 4000, 'example': 'This cleared up the deployment flow.'}}, 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, ) async def create_blog_post_comment( self, @@ -298,7 +298,7 @@ class BlogOpenapiAgent(A2AAgent): description="PUT /api/posts/{slug}/reaction - Set the viewer reaction", tags=('Reactions',), timeout_seconds=120, - input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'$ref': '#/components/schemas/BlogReactionInput', 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, + input_schema={'type': 'object', 'properties': {'parameters': {'type': 'object', 'properties': {'slug': {'type': 'string', 'minLength': 1, 'maxLength': 120, 'example': 'shipping-agents-with-receipts', 'description': 'Post slug. The API normalizes path slugs to lowercase kebab-case before lookup.'}}, 'required': ['slug'], 'additionalProperties': False}, 'body': {'type': 'object', 'required': ['reaction'], 'properties': {'reaction': {'oneOf': [{'type': 'string', 'enum': ['like', 'dislike']}, {'type': 'null'}], 'description': "Set to null to clear the viewer's reaction."}}, 'description': 'JSON request body.'}}, 'required': ['parameters', 'body'], 'additionalProperties': False}, ) async def set_blog_post_reaction( self,