From 5da42253facc37bc17b932615a77ccb84fd2ea88 Mon Sep 17 00:00:00 2001 From: robert Date: Sat, 18 Jul 2026 13:50:46 -0300 Subject: [PATCH] feat: generate improvement proposals --- .a2a/agent.dsl.json | 11 ++++++++--- README.md | 6 +++++- a2a.yaml | 2 +- agent.py | 20 ++++++++++++++++---- tests/test_agent.py | 2 +- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/.a2a/agent.dsl.json b/.a2a/agent.dsl.json index 46ff4b0..50a6854 100644 --- a/.a2a/agent.dsl.json +++ b/.a2a/agent.dsl.json @@ -2,8 +2,8 @@ "schema_version": "2026-06-04", "language": "python", "name": "agent-reviewer", - "description": "Audit an A2A agent's source before deploy. Reads the target repo from Gitea, applies security / best-practice / grant-scope skill bundles, and returns a structured ReviewReport.", - "version": "0.1.1", + "description": "Pre-deploy audit of an A2A agent's source — security, scope, ergonomics.", + "version": "0.1.2", "entrypoint": { "module": "agent", "class_name": "AgentReviewer", @@ -56,6 +56,9 @@ "type": "null" } ] + }, + "mode": { + "type": "string" } }, "required": [ @@ -83,6 +86,7 @@ }, "runtime": { "lifecycle": "ephemeral", + "availability": "on_demand", "state": "none", "sandbox": "microsandbox", "resources": { @@ -115,6 +119,7 @@ "memory": null, "databases": [] }, + "endpoints": [], "apt_packages": [] }, "template_lineage": null, @@ -151,7 +156,7 @@ "source": "python-a2a-pack", "project_manifest": { "name": "agent-reviewer", - "version": "0.1.1", + "version": "0.1.2", "entrypoint": "agent:AgentReviewer" } } diff --git a/README.md b/README.md index 9c84dd6..bb176f8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ returns a typed `ReviewReport`. ## Skill: `review` ``` -review(agent_name: str, ref: str = "main", owner: str | None = None) -> ReviewReport +review(agent_name: str, ref: str = "main", owner: str | None = None, mode: str = "audit") -> ReviewReport ``` Workflow: @@ -19,6 +19,10 @@ Workflow: (`a2a card`, `ruff`), produce findings. 4. Release the Gitea token in `finally`. +`mode="improvements"` keeps the same read-only checks and additionally asks +for at most three source-specific robustness, test, tool-usability, or +operator-ergonomics ideas. Agent Studio uses that mode for its daily review. + ## Output `ReviewReport`: diff --git a/a2a.yaml b/a2a.yaml index 9a37283..b9422ec 100644 --- a/a2a.yaml +++ b/a2a.yaml @@ -1,5 +1,5 @@ name: agent-reviewer -version: 0.1.1 +version: 0.1.2 entrypoint: agent:AgentReviewer description: Pre-deploy audit of an A2A agent's source — security, scope, ergonomics. expose: diff --git a/agent.py b/agent.py index 61b0776..8a7c83b 100644 --- a/agent.py +++ b/agent.py @@ -8,8 +8,9 @@ from typing import Any from pydantic import BaseModel +import a2a_pack as a2a from a2a_pack import ( - A2AAgent, LLMProvisioning, NoAuth, Pricing, RunContext, skill, + A2AAgent, LLMProvisioning, NoAuth, Pricing, RunContext, ) from agent_reviewer import ReviewerContext, build_reviewer_graph @@ -30,7 +31,7 @@ class AgentReviewer(A2AAgent[ReviewerConfig, NoAuth]): "repo from Gitea, applies security / best-practice / grant-scope " "skill bundles, and returns a structured ReviewReport." ) - version = "0.1.1" + version = "0.1.2" config_model = ReviewerConfig auth_model = NoAuth @@ -46,7 +47,7 @@ class AgentReviewer(A2AAgent[ReviewerConfig, NoAuth]): ), ) - @skill( + @a2a.tool( description=( "Audit an agent's source. Pass the target ``agent_name`` " "(kebab-case) and optional ``ref`` (defaults to ``main``). " @@ -63,6 +64,7 @@ class AgentReviewer(A2AAgent[ReviewerConfig, NoAuth]): agent_name: str, ref: str = "main", owner: str | None = None, + mode: str = "audit", ) -> dict[str, Any]: if not _is_valid_slug(agent_name): return {"error": f"invalid agent_name {agent_name!r} — use kebab-case"} @@ -120,11 +122,21 @@ class AgentReviewer(A2AAgent[ReviewerConfig, NoAuth]): completion_box=completion_box, ) + improvement_brief = ( + " This is a daily improvement-discovery review. In addition to real " + "defects, return at most three high-confidence, source-specific ideas " + "that improve robustness, test coverage, tool usability, or operator " + "ergonomics. Represent an idea as an info/ergonomics finding and put " + "the concrete implementation in suggestion. Do not invent work for a " + "clean agent." + if str(mode).strip().lower() == "improvements" + else "" + ) user_msg = ( f"Review the agent at ``{gitea_owner}/{agent_name}`` ref ``{ref}``. " "Read the source, consult the bundled skills, run the sandbox checks, " "then call ``submit_review_report`` exactly once with the structured " - "report." + f"report.{improvement_brief}" ) async def _heartbeat() -> None: diff --git a/tests/test_agent.py b/tests/test_agent.py index 6b2bcf4..4de1c1f 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -21,7 +21,7 @@ from agent_reviewer.config import load_settings # noqa: E402 def test_class_metadata() -> None: assert AgentReviewer.name == "agent-reviewer" - assert AgentReviewer.version == "0.1.1" + assert AgentReviewer.version == "0.1.2" assert AgentReviewer.wants_cp_jwt is True assert AgentReviewer.pricing.price_per_call_usd == 0.05 assert AgentReviewer.pricing.caller_pays_llm is True