Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ The core philosophy is **State-first, Evidence-first**: instead of asking "what
```
Phase 2B: substantially complete
Phase 2C: internal technical validation complete
State–Evidence production cutover phase 1: complete
Real teaching validation: not started
Production v2 cutover: not started
LLM upstream migration: pending
```

The codebase now has a complete production pipeline — from material upload and AI analysis to teaching kernel generation, courseware review, auto-revision, dual HTML/PPTX export, and quality gates.
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**AI 辅助语言教学课件生成器 — 面向国际中文教育**

[![测试](https://img.shields.io/badge/tests-498%20passed-brightgreen)](#)
[![测试](https://img.shields.io/badge/tests-652%20passed-brightgreen)](#)
[![阶段](https://img.shields.io/badge/phase-2C%20内部验证-yellow)](#)
[![许可](https://img.shields.io/badge/license-MIT-blue)](#)

Expand All @@ -29,11 +29,12 @@ HanClassStudio 是一个开源的 AI 辅助互动课件生成系统,专为**
```
Phase 2B:基本完成
Phase 2C:内部技术验证完成
State–Evidence 生产 cutover 第一阶段:完成
真实教学验证:尚未开始
生产 v2 cutover:尚未开始
LLM 上游迁移:待完成
```

当前代码库已具备完整的功能流水线:从教材上传、AI 分析、教学内核生成、课件审校、自动修订,到 HTML/PPTX 双端导出和质量门禁。
当前代码库已具备完整的功能流水线:从教材上传、AI 分析、State–Evidence 教学内核、Canonical Presentation Blueprint、兼容适配器、课件审校,到 HTML/PPTX 双端导出和质量门禁。生产 `LessonBlueprint` 只作为 Renderer 兼容产物生成,不能绕过教学内核

**下一步优先事项**:进行三节真实中文微课的教师主导 Pilot。浏览器自动化是并行支撑项,不阻塞真实审课。欢迎关注和贡献。

Expand Down Expand Up @@ -157,7 +158,7 @@ npm run test:api # 仅后端测试
npm run build:web # 前端构建校验
```

当前 Phase 2C 门禁:**647 passed,3 skipped**(后端)+ 前端构建/状态契约 + **14 passed** Playwright;大型真实生图生命周期为显式 opt-in。
当前生产 cutover 门禁:**652 passed,3 skipped**(后端)+ 前端构建/状态契约;大型真实生图生命周期为显式 opt-in。

---

Expand Down
3 changes: 3 additions & 0 deletions apps/api/src/hcs_api/activity_planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def _activity_for_evidence(evidence: EvidenceSpec, learner_level: str) -> Learni
"matching": "match_pairs",
"role_play": "role_play",
}.get(evidence.evidence_type, "guided_response")
if "character_formation" in evidence.evidence_id:
activity_type = "character_formation"
teacher_only = False
return LearningActivity(
id=evidence.collector_refs[0] if evidence.collector_refs else f"act_{evidence.evidence_id}",
evidence_ids=[evidence.evidence_id],
Expand Down
31 changes: 23 additions & 8 deletions apps/api/src/hcs_api/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ def validate_agent_output(project_id: str) -> AgentValidation:
required = [
"specs/lesson_spec.md",
"specs/spec_lock.json",
"learning/learning_state_plan.json",
"learning/evidence_plan.json",
"learning/activity_plan.json",
"quality/evidence_alignment_report.json",
"presentation/presentation_content_plan.json",
"presentation/presentation_media_request_plan.json",
"presentation/abstract_activity_bindings.json",
"presentation/presentation_blueprint.json",
"presentation/legacy_component_mapping.json",
"presentation/legacy_blueprint_provenance.json",
"quality/presentation_content_report.json",
"quality/presentation_media_request_report.json",
"quality/presentation_readiness_report.json",
"presentation/activity_bindings.json",
"blueprints/lesson_blueprint.json",
"blueprints/interaction_plan.json",
"blueprints/media_plan.json",
Expand Down Expand Up @@ -100,14 +114,14 @@ def _build_task_text(project_id: str, route: str, mode: str) -> str:

- `specs/lesson_spec.md`
- `specs/spec_lock.json`
- `blueprints/lesson_blueprint.json`
- `blueprints/interaction_plan.json`
- `blueprints/media_plan.json`
- `assets/data/asset_manifest.json` only when media references change
- `learning/learning_state_plan.json`
- `learning/evidence_plan.json`
- `learning/activity_plan.json`

`blueprints/lesson_blueprint.json` is a legacy presentation contract. Agents may edit display-safe
presentation structure, but must not add or redefine learning goals, evidence specs, learning
activities, learner-state assumptions, teacher-only evidence rules, or quality judgments there.
`blueprints/lesson_blueprint.json` is a read-only legacy renderer compatibility artifact. It is
created only by the canonical presentation adapter. Do not edit it, `presentation/presentation_blueprint.json`,
media plans, rendered HTML, or exports. Revise the State-Evidence artifacts above, then ask
HanClassStudio to regenerate canonical presentation and compatibility outputs.

After editing, ask HanClassStudio to validate agent output, then render, run the quality gate, and export only if quality allows it.
"""
Expand All @@ -123,7 +137,8 @@ def _build_rules_text() -> str:
- Chinese is always the target language.
- The scaffolding language supports comprehension only; it must not replace Chinese input or output.
- Do not bypass the quality gate.
- Treat `blueprints/lesson_blueprint.json` as presentation-only compatibility output, never pedagogical truth.
- Treat `blueprints/lesson_blueprint.json` as read-only presentation compatibility output, never pedagogical truth.
- Never edit or regenerate the legacy Blueprint directly; use the State-Evidence blueprint stage.
- Do not add learning goals, evidence specs, activity selection policy, or teacher-only notes to learner-facing blueprint data.
"""

Expand Down
15 changes: 13 additions & 2 deletions apps/api/src/hcs_api/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ def _estimate_duration(source: SourceMaterial) -> str:
return f"{estimated} minutes"


def build_blueprint(
def build_legacy_diagnostic_blueprint(
source: SourceMaterial,
profile: LessonProfile,
candidates: TeachingCandidates | None = None,
language_items: list | None = None,
) -> LessonBlueprint:
"""Build lesson blueprint from source material and optional teaching candidates."""
"""Build a direct Source-to-Slides fixture for diagnostics and regression only."""
from .analysis import extract_candidates

if candidates is None:
Expand Down Expand Up @@ -207,9 +207,20 @@ def build_blueprint(
grammar_points=grammar_points,
slides=slides,
route_hint=route,
artifact_role="legacy_diagnostic",
)


def build_blueprint(
source: SourceMaterial,
profile: LessonProfile,
candidates: TeachingCandidates | None = None,
language_items: list | None = None,
) -> LessonBlueprint:
"""Compatibility alias for the explicit legacy diagnostic builder."""
return build_legacy_diagnostic_blueprint(source, profile, candidates, language_items)


# ── Objective building ──

def _build_objectives(topic: str, route: RouteHint, profile: LessonProfile) -> list[str]:
Expand Down
5 changes: 4 additions & 1 deletion apps/api/src/hcs_api/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@


# High-priority greeting words — these are core for greeting_lesson route
GREETING_WORDS = {"你好", "您好", "你", "您", "你们", "好", "再见", "谢谢", "不客气", "对不起", "没关系"}
GREETING_WORDS = {
"你好", "您好", "你", "您", "你们", "好", "老师好", "早上好",
"再见", "谢谢", "不客气", "对不起", "没关系",
}

# Stroke/numeral noise — not real vocabulary in teaching context
STROKE_NOISE = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "横", "竖", "撇", "捺", "点", "提", "折", "钩"}
Expand Down
Loading
Loading