This commit is contained in:
a2a-platform
2026-06-29 00:46:25 +00:00
parent e45ff7e55d
commit eaaa1f2e0e
6 changed files with 50 additions and 4 deletions

View File

@@ -63,9 +63,17 @@ class OperationInput(BaseModel):
class LearnhouseAgent(A2AAgent):
name = "learnhouse-agent"
description = "LearnHouse is an open-source platform tailored for learning experiences."
version = "1.2.9"
version = "1.2.10"
consumer_setup = ConsumerSetup.from_fields(
ConsumerSetupField.config("OPENAPI_BASE_URL", label="API base URL", description="Override the default API server (https://learnhouse.a2acloud.io).", required=False, input_type="url"),
ConsumerSetupField.secret(
"LEARNHOUSE_AUTH",
label="LearnHouse auth",
description=(
"Paste a LearnHouse user auth value: either 'Bearer <access_token>', "
"a raw access token, or a Cookie header such as 'LH_access=...; LH_refresh=...'."
),
),
)
llm_provisioning = LLMProvisioning.PLATFORM
pricing = Pricing(
@@ -383,6 +391,7 @@ class LearnhouseAgent(A2AAgent):
raise ValueError("missing required path parameter(s): " + missing)
if cookies:
headers["cookie"] = "; ".join(f"{key}={value}" for key, value in cookies.items())
headers.update(_learnhouse_auth_headers(ctx))
auth_headers, auth_query = self._auth_for_operation(ctx, operation)
headers.update(auth_headers)
query.update(auth_query)
@@ -446,6 +455,25 @@ def _consumer_secret_optional(ctx: RunContext, name: str | None) -> str:
return ""
def _learnhouse_auth_headers(ctx: RunContext) -> dict[str, str]:
raw = ctx.consumer_secret("LEARNHOUSE_AUTH").strip()
if not raw:
raise ConsumerSetupMissing("operation requires consumer setup secret(s): LEARNHOUSE_AUTH")
lower = raw.lower()
if lower.startswith("authorization:"):
value = raw.split(":", 1)[1].strip()
return {"authorization": value}
if lower.startswith("cookie:"):
value = raw.split(":", 1)[1].strip()
return {"cookie": value}
if lower.startswith("bearer "):
return {"authorization": raw}
if "=" in raw and (";" in raw or lower.startswith("lh_") or "session" in lower):
return {"cookie": raw}
return {"authorization": f"Bearer {raw}"}
def _request_body_content_types(operation: dict[str, Any]) -> set[str]:
request_body = operation.get("request_body")
if not isinstance(request_body, dict):