This commit is contained in:
a2a-platform
2026-06-29 01:09:08 +00:00
parent eaaa1f2e0e
commit 5cf3dbe409
7 changed files with 64 additions and 5 deletions

View File

@@ -3,7 +3,7 @@
"language": "python", "language": "python",
"name": "learnhouse-agent", "name": "learnhouse-agent",
"description": "LearnHouse is an open-source platform tailored for learning experiences.", "description": "LearnHouse is an open-source platform tailored for learning experiences.",
"version": "1.2.10", "version": "1.2.11",
"entrypoint": { "entrypoint": {
"module": "agent", "module": "agent",
"class_name": "LearnhouseAgent", "class_name": "LearnhouseAgent",
@@ -172,7 +172,7 @@
"source": "python-a2a-pack", "source": "python-a2a-pack",
"project_manifest": { "project_manifest": {
"name": "learnhouse-agent", "name": "learnhouse-agent",
"version": "1.2.10", "version": "1.2.11",
"entrypoint": "agent:LearnhouseAgent" "entrypoint": "agent:LearnhouseAgent"
} }
} }

View File

@@ -17,6 +17,14 @@ Deployment context:
LearnHouse Enterprise multi-organization mode. LearnHouse Enterprise multi-organization mode.
- Course creation uses multipart form fields: `name`, `description`, `public`, - Course creation uses multipart form fields: `name`, `description`, `public`,
and `about`. and `about`.
- When creating lesson/module content, create at least one activity per chapter
using that chapter's own `chapter_id`. Do not attach all activities to the
first chapter.
- Visible lesson activities should normally use `TYPE_DYNAMIC` /
`SUBTYPE_DYNAMIC_MARKDOWN`, markdown content/details, `lock_type=public`, and
`published=true` unless the user explicitly asks for drafts.
- Activity updates must not send `published_version`; this LearnHouse backend
currently rejects that field.
- Auth setup is required as `LEARNHOUSE_AUTH`. Use `Bearer <access_token>`, a - Auth setup is required as `LEARNHOUSE_AUTH`. Use `Bearer <access_token>`, a
raw access token, or a Cookie header containing `LH_access`/`LH_refresh`. raw access token, or a Cookie header containing `LH_access`/`LH_refresh`.

View File

@@ -1,5 +1,5 @@
name: learnhouse-agent name: learnhouse-agent
version: 1.2.10 version: 1.2.11
entrypoint: agent:LearnhouseAgent entrypoint: agent:LearnhouseAgent
description: LearnHouse is an open-source platform tailored for learning experiences. description: LearnHouse is an open-source platform tailored for learning experiences.
runtime: runtime:

View File

@@ -48,7 +48,17 @@ LEARNHOUSE_CONTEXT = (
"When creating a course, send multipart form fields name, description, " "When creating a course, send multipart form fields name, description, "
"public, and about; if the user only gives a title, use it as name, provide " "public, and about; if the user only gives a title, use it as name, provide "
"short description/about text, and set public=false unless the user asks " "short description/about text, and set public=false unless the user asks "
"for a public course." "for a public course. When asked to create a course with lessons or modules, "
"create the course, create each chapter with the returned course_id, then "
"create at least one activity in each chapter using that chapter's specific "
"chapter_id. Do not attach all activities to the first chapter. For visible "
"lesson content, create activities with activity_type TYPE_DYNAMIC, "
"activity_sub_type SUBTYPE_DYNAMIC_MARKDOWN, markdown content/details, "
"lock_type public, and published=true unless the user requests drafts. "
"After writing course content, verify every chapter has at least one "
"activity through course metadata or the chapter activity endpoint. When "
"updating activities, do not send published_version; this LearnHouse "
"backend currently rejects that field."
) )
@@ -63,7 +73,7 @@ class OperationInput(BaseModel):
class LearnhouseAgent(A2AAgent): class LearnhouseAgent(A2AAgent):
name = "learnhouse-agent" name = "learnhouse-agent"
description = "LearnHouse is an open-source platform tailored for learning experiences." description = "LearnHouse is an open-source platform tailored for learning experiences."
version = "1.2.10" version = "1.2.11"
consumer_setup = ConsumerSetup.from_fields( 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.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( ConsumerSetupField.secret(
@@ -291,6 +301,18 @@ class LearnhouseAgent(A2AAgent):
"For LearnHouse course creation, send body/form fields: " "For LearnHouse course creation, send body/form fields: "
"name, description, public, about." "name, description, public, about."
) )
if _is_learnhouse_create_activity(operation):
parts.append(
"For LearnHouse activity creation, send JSON fields name, "
"chapter_id, activity_type, activity_sub_type, content, "
"details, lock_type, and published. Use the target "
"chapter's own chapter_id; do not reuse the first chapter ID."
)
if _is_learnhouse_update_activity(operation):
parts.append(
"Do not send published_version on LearnHouse activity "
"updates; this backend rejects that field."
)
parts.append(f"Operation ID: {operation['operation_id']}") parts.append(f"Operation ID: {operation['operation_id']}")
return "\n".join(part for part in parts if part) return "\n".join(part for part in parts if part)
@@ -500,6 +522,20 @@ def _is_learnhouse_create_course(operation: dict[str, Any]) -> bool:
) )
def _is_learnhouse_create_activity(operation: dict[str, Any]) -> bool:
return (
str(operation.get("operation_id") or "")
== "api_create_activity_api_v1_activities_post"
)
def _is_learnhouse_update_activity(operation: dict[str, Any]) -> bool:
return (
str(operation.get("operation_id") or "")
== "api_update_activity_api_v1_activities_activity_uuid_put"
)
def _apply_learnhouse_defaults( def _apply_learnhouse_defaults(
operation: dict[str, Any], operation: dict[str, Any],
parameters: dict[str, Any], parameters: dict[str, Any],

View File

@@ -11,6 +11,14 @@ Use the generated operation tools to make real API calls. Do not invent API resp
If a tool reports missing setup, return the exact setup field name to the caller. If a tool reports missing setup, return the exact setup field name to the caller.
For write, update, or delete operations, state the intended action before calling the tool. For write, update, or delete operations, state the intended action before calling the tool.
For visible lesson content, prefer `POST /api/v1/activities/` with
`activity_type=TYPE_DYNAMIC`, `activity_sub_type=SUBTYPE_DYNAMIC_MARKDOWN`,
markdown stored in `content`/`details`, `lock_type=public`, and `published=true`
unless the user asks for drafts. Always use the target chapter's own
`chapter_id`; do not attach every activity to the first chapter. On
`PUT /api/v1/activities/{activity_uuid}`, do not send `published_version`;
this LearnHouse backend rejects that field.
## Operations ## Operations
### api_create_activity_api_v1_activities_post ### api_create_activity_api_v1_activities_post

View File

@@ -11,6 +11,11 @@ Use the generated operation tools to make real API calls. Do not invent API resp
If a tool reports missing setup, return the exact setup field name to the caller. If a tool reports missing setup, return the exact setup field name to the caller.
For write, update, or delete operations, state the intended action before calling the tool. For write, update, or delete operations, state the intended action before calling the tool.
When creating multiple lesson chapters for a course, keep the returned `id` for
each chapter. If the user requested course content, create at least one activity
for every chapter using that specific `chapter_id`; do not reuse the first
chapter ID for all activities. Verify every chapter has at least one activity.
## Operations ## Operations
### api_create_coursechapter_api_v1_chapters_post ### api_create_coursechapter_api_v1_chapters_post

View File

@@ -20,6 +20,8 @@ Deployment context for this LearnHouse instance:
- When listing courses and the user does not provide pagination, use `page=1` and `limit=50`. - When listing courses and the user does not provide pagination, use `page=1` and `limit=50`.
- When creating a course, use query parameter `org_id=1` unless the user explicitly provides another org ID. - When creating a course, use query parameter `org_id=1` unless the user explicitly provides another org ID.
- Course creation must send multipart form fields `name`, `description`, `public`, and `about`. If the user only gives a title, use it as `name`, provide short `description` and `about` values, and set `public=false` unless the user asks for a public course. - Course creation must send multipart form fields `name`, `description`, `public`, and `about`. If the user only gives a title, use it as `name`, provide short `description` and `about` values, and set `public=false` unless the user asks for a public course.
- When the user asks for a course with lessons, modules, or activities, do not stop after creating the course and chapters. Create at least one activity per chapter, using each chapter's own returned `chapter_id`.
- Do not attach all generated activities to the first chapter. Verify the resulting course metadata shows activities distributed under the intended chapters.
- Course creation and course management require `LEARNHOUSE_AUTH` consumer setup. - Course creation and course management require `LEARNHOUSE_AUTH` consumer setup.
## Operations ## Operations