fix: generate agents with platform LLM grants
All checks were successful
build / build (push) Successful in 21s

This commit is contained in:
robert
2026-05-26 21:39:02 -03:00
parent 54b0788b82
commit 53ecc9a0cb
11 changed files with 74 additions and 40 deletions

View File

@@ -1,6 +1,6 @@
---
name: a2apack-agent-authoring
description: Author production a2a-pack agents with clear public @skill schemas, runtime declarations, caller-provided LLMs, workspace grants, pricing, resources, and secure platform capabilities. Use when writing or reviewing agent.py for an A2A agent.
description: Author production a2a-pack agents with clear public @skill schemas, runtime declarations, platform LLM grants, optional caller-provided LLMs, workspace grants, pricing, resources, and secure platform capabilities. Use when writing or reviewing agent.py for an A2A agent.
---
# A2A Pack Agent Authoring
@@ -21,13 +21,16 @@ Use `A2AAgent` class attributes for runtime and marketplace behavior:
- `wants_cp_jwt=True` is only for trusted platform agents. It forwards the
caller's control-plane token.
For generated/user-owned agents that call an LLM, default to
`LLMProvisioning.CALLER_PROVIDED` with `Pricing(..., caller_pays_llm=True, ...)`.
Use `LLMProvisioning.PLATFORM` only when the user explicitly wants
platform-paid LLM usage. Reserve `LLMProvisioning.PLATFORM_OR_CALLER_PROVIDED`
For hosted generated/user-owned agents that call an LLM, default to
`LLMProvisioning.PLATFORM` with `Pricing(..., caller_pays_llm=False, ...)` so
main-agent handoffs mint a scoped A2A LiteLLM grant for the callee. Use
`LLMProvisioning.CALLER_PROVIDED` only when the user explicitly wants BYOK or
caller-paid inference. Reserve `LLMProvisioning.PLATFORM_OR_CALLER_PROVIDED`
for trusted platform/meta agents that must work with either the caller's
selected creds or a platform fallback grant. In every mode, read `ctx.llm`;
never read `A2A_LITELLM_KEY`, provider keys, or platform secrets directly.
never read `A2A_LITELLM_KEY`, `OPENAI_API_KEY`, provider keys, or platform
secrets directly. If `ctx.llm.api_key` is empty, return a clear setup/config
result before constructing `ChatOpenAI`.
Keep each `@skill` method `async`, put `RunContext[...]` immediately after
`self`, and annotate every public argument. Do not use `*args` or `**kwargs`;
@@ -68,11 +71,11 @@ class ResearchAgent(A2AAgent[ResearchConfig, NoAuth]):
config_model = ResearchConfig
auth_model = NoAuth
llm_provisioning = LLMProvisioning.CALLER_PROVIDED
llm_provisioning = LLMProvisioning.PLATFORM
pricing = Pricing(
price_per_call_usd=0.05,
caller_pays_llm=True,
notes="Caller supplies LLM credentials through the platform.",
caller_pays_llm=False,
notes="Uses a scoped platform LLM grant through ctx.llm.",
)
resources = Resources(cpu="1", memory="1Gi", max_runtime_seconds=900)
egress = EgressPolicy(allow_hosts=("api.openai.com",))
@@ -97,6 +100,12 @@ class ResearchAgent(A2AAgent[ResearchConfig, NoAuth]):
) -> dict[str, Any]:
creds = ctx.llm
await ctx.emit_progress(f"researching with {creds.model}")
if not creds.api_key:
return {
"summary": "LLM credentials were not available for this run.",
"artifact": None,
"path": save_path,
}
graph = self._build_graph(ctx)
state = await graph.ainvoke(
{