Skip to content

Iris: Merge chattype-specific pipelines into a single chat pipeline#434

Open
Senan04 wants to merge 53 commits intomainfrom
iris/chore/unify-chat-pipelines
Open

Iris: Merge chattype-specific pipelines into a single chat pipeline#434
Senan04 wants to merge 53 commits intomainfrom
iris/chore/unify-chat-pipelines

Conversation

@Senan04
Copy link
Copy Markdown

@Senan04 Senan04 commented Feb 24, 2026

This needs to be tested together with the corresponding Artemis PR.

Closes IRIS-96

Motivation and Context

The codebase previously had four separate chat pipelines — CourseChatPipeline,
ExerciseChatPipeline, LectureChatPipeline, and TextExerciseChatPipeline —
each with their own pipeline-specific DTOs, status update classes, prompt
templates, and API endpoints. This led to significant code duplication,
inconsistent behavior across chat modes, and high maintenance overhead
whenever cross-cutting changes (e.g. system prompt updates, tool logic, status
handling) needed to be applied.

Description

This PR unifies all four chat pipelines into a single ChatPipeline that
handles all chat modes via an IrisChatMode discriminator field:

  • DTOs: Removed CourseChatPipelineExecutionDTO,
    ExerciseChatPipelineExecutionDTO, LectureChatPipelineExecutionDTO, and
    TextExerciseChatPipelineExecutionDTO in favour of a single
    ChatPipelineExecutionDTO containing all context-specific fields. Similarly,
    ExtendedCourseDTO was merged into CourseDTO.
  • Pipeline: The four pipeline classes were replaced by a single ChatPipeline
    class. Mode-specific behaviour is branched internally based on IrisChatMode.
  • Tools: Introduced ChatToolProviders to centralise tool availability logic,
    decoupling it from pipeline context.
  • Status updates: Unified pipeline-specific status update DTOs into a single
    ChatStatusUpdateDTO.
  • System prompt: Replaced four separate Jinja2 prompt templates with a single
    chat_system_prompt.j2.
  • API: Replaced multiple pipeline-specific HTTP endpoints with a single /chat
    endpoint in pipelines.py.

Summary by CodeRabbit

  • New Features

    • Single unified chat endpoint with selectable chat modes (course, lecture, programming/text exercise).
    • Dynamic tool providers (lecture/FAQ/memory/MCQ) and MCQ parallel mode.
  • Behavior & UX

    • New consolidated system prompt with improved tutoring guidance, language handling, integrity rules, and MCQ flows.
    • Richer chat context: expanded course/exercise metadata, session title generation, and improved citation/reference handling.
  • Architecture & API Changes

    • Consolidated chat pipelines and status callbacks into one mode-driven implementation.

…ant / ExerciseChatVariant / TextExerciseChatVariant in the future
…seChatPipeline / TextExerciseChatPipeline / LectureChatPipeline, init implemented, Add empty ChatSystemPrompt
…t(), on_agent_step(), is_memiris_memory_creation_enabled()
…pelines.py to use ChatPipeline instead of the different Pipelines.
…xerciseDTO inherit from, Unify pipeline specific DTO's into ChatPipelineExecutionDTO -> Update usages.
… pipeline specific status update dto's in ChatStatusUpdateDTO => Update usage of DTO's in status_update.py
…s, simplify is_memiris_memory_creation_enabled, uniform event handling.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Consolidates mode-specific chat pipelines into a single mode-parameterized ChatPipeline, unifies DTOs/status callbacks/templates/tools/endpoints, introduces provider-driven tool loading, adds an IrisChatMode enum and prepare_state hook, and replaces multiple prompt templates with a single conditional chat_system_prompt.j2.

Changes

Cohort / File(s) Summary
Top-level DTO exports
iris/src/iris/domain/__init__.py
Removed re-exports for mode-specific chat DTOs (CourseChatPipelineExecutionDTO, ExerciseChatPipelineExecutionDTO, ChatPipelineExecutionBaseDataDTO).
Deleted per-mode DTOs & event
iris/src/iris/domain/chat/chat_pipeline_execution_base_data_dto.py, iris/src/iris/domain/chat/course_chat/..., iris/src/iris/domain/chat/exercise_chat/..., iris/src/iris/domain/chat/lecture_chat/..., iris/src/iris/domain/chat/text_exercise_chat/..., iris/src/iris/domain/event/pyris_event_dto.py
Removed multiple per-mode execution DTOs and the generic PyrisEventDTO.
Unified Chat DTO changes
iris/src/iris/domain/chat/chat_pipeline_execution_dto.py
Expanded ChatPipelineExecutionDTO with chat_mode (alias chatMode), made user required, added course, metrics, lecture, lectureUnitId, customInstructions, separated programming/text exercise & submission fields, and other context fields.
Status DTOs / updates
iris/src/iris/domain/status/chat_status_update_dto.py
Renamed/merged status DTO to unified ChatStatusUpdateDTO and changed suggestions to use Field(default_factory=list); adjusted imports/renames.
Removed mode-specific status DTOs
iris/src/iris/domain/chat/exercise_chat/exercise_chat_status_update_dto.py, iris/src/iris/domain/status/lecture_chat_status_update_dto.py, iris/src/iris/domain/status/text_exercise_chat_status_update_dto.py
Deleted per-mode status DTO classes.
Course & exercise DTOs
iris/src/iris/domain/data/course_dto.py, iris/src/iris/domain/data/extended_course_dto.py, iris/src/iris/domain/data/programming_exercise_dto.py, iris/src/iris/domain/data/text_exercise_dto.py
Extended CourseDTO with scheduling/settings lists and analytics flag; removed ExtendedCourseDTO; changed ProgrammingExerciseDTO (nametitle, consolidated optional fields); removed course from TextExerciseDTO and defaulted title.
Pipeline refactor & hook
iris/src/iris/pipeline/chat/iris_chat_mode.py, iris/src/iris/pipeline/chat/chat_pipeline.py, iris/src/iris/pipeline/chat/course_chat_pipeline.py, iris/src/iris/pipeline/chat/lecture_chat_pipeline.py, iris/src/iris/pipeline/chat/text_exercise_chat_pipeline.py, iris/src/iris/pipeline/abstract_agent_pipeline.py
Added IrisChatMode enum; introduced unified ChatPipeline (replacing Course/Lecture/Text/Exercise pipelines) and removed those pipeline files; extended AbstractAgentPipeline with prepare_state and new state fields (query_text, storages, allow_* flags); integrated MCQ parallel flow and tool-provider usage.
Prompt templates
iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2, (removed) .../course_chat_system_prompt.j2, .../exercise_chat_system_prompt.j2, .../lecture_chat_system_prompt.j2, .../text_exercise_chat_system_prompt.j2
Added unified chat_system_prompt.j2 with conditional behavior and MCQ handling; removed four mode-specific prompt templates.
Tool provider system
iris/src/iris/tools/chat_tool_providers.py, iris/src/iris/tools/course_details.py
Added chat_tool_providers.py with ordered provider functions (CHAT_TOOL_PROVIDERS) to assemble tools by state; simplified create_tool_get_course_details to accept only CourseDTO and removed ExtendedCourseDTO branching.
Web/API & workers
iris/src/iris/web/routers/pipelines.py
Replaced multiple chat endpoints with single POST /chat/run and run_chat_pipeline_worker using ChatPipelineExecutionDTO; removed mode-specific route handlers/workers.
Status callbacks & routes
iris/src/iris/web/status/status_update.py
Consolidated four chat-specific callbacks into ChatStatusCallback(chat_mode: IrisChatMode); unified endpoint paths to /chat/...; stages now derived from _CHAT_MODE_STAGES.
Health/features & registry
iris/src/iris/web/routers/health/Pipelines/features.py, .../registery.py
Replaced four feature enum members with Features.CHAT; mapped Features.CHATChatPipeline and updated PipelineType/PIPELINE_BY_FEATURE.
Tracing
iris/src/iris/tracing/langfuse_tracer.py
Trace extraction now prefers dto.programming_exercise or dto.text_exercise for exercise metadata instead of dto.exercise.
Tests
iris/tests/test_mcq_prompt_rendering.py
Updated tests to use unified _base_context() and render chat_system_prompt.j2 (replacing per-mode template usage).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client/API
    participant Router as Web Router
    participant Pipeline as ChatPipeline
    participant Providers as CHAT_TOOL_PROVIDERS
    participant Agent as Agent/LLM
    participant Callback as Status Callback

    Client->>Router: POST /chat/run (ChatPipelineExecutionDTO)
    Router->>Pipeline: instantiate ChatPipeline(chat_mode)
    Router->>Pipeline: __call__(dto, ChatStatusCallback)

    Pipeline->>Pipeline: prepare_state(state) (set query_text, storages, allow_* flags)

    Pipeline->>Providers: iterate providers with state
    Providers-->>Pipeline: list of tool factories (filtered by state)

    Pipeline->>Agent: build_system_message (render chat_system_prompt.j2)
    Pipeline->>Agent: run agent with prompt + tools

    alt MCQ parallel path
        Pipeline->>Pipeline: mcq_pre_agent_hook & mcq_execute_agent
    else normal
        Agent->>Pipeline: agent response
    end

    Pipeline->>Pipeline: post_agent_hook (citations, refine, session title)
    Pipeline->>Callback: final status update (response, session_title)
    Callback->>Client: deliver status updates (/chat endpoints)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

A rabbit hops through chat with glee, 🐰
Four pipes folded into one tidy tree,
Modes wear a crown, prompts now unified,
Tools wake by state, DTOs clarified,
Hooray — one chat pipeline bounces free! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main change: consolidating multiple chat-type-specific pipelines into a single unified chat pipeline.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch iris/chore/unify-chat-pipelines

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the iris label Feb 24, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 3, 2026

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Mar 3, 2026
@bassner bassner added this to the 2.0.0 milestone Mar 13, 2026
@github-actions github-actions Bot removed the stale label Mar 14, 2026
@github-actions
Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Mar 22, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2`:
- Around line 72-82: The template currently always prints the text-exercise line
because exercise_id is truthy for both types; update the Jinja block so the
text-specific field only renders when text_exercise_submission is present (e.g.,
check if text_exercise_submission is not null/empty) and similarly render
programming-specific fields like programming_language only when
programming_language is set, ensuring lines like "- **Student's Current Text
Exercise Submission**: {{ text_exercise_submission }}" and "- **Programming
Language**: {{ programming_language }}" are each wrapped in their own {% if %}
guards so they only appear for the appropriate exercise type.
- Around line 258-281: The template currently shows MCQ tool instructions even
when the MCQ tool is not available (mcq_parallel is only set for
IrisChatMode.COURSE/LECTURE and provide_mcq_generation returns None for
programming/text exercises), causing exercise chats to attempt
generate_mcq_questions incorrectly; fix by gating the entire MCQ branch on a
real availability flag (e.g., add an allow_mcq_tool boolean populated in
prepare_agent/build_system_message—mirroring
allow_lecture_tool/allow_faq_tool—or use a check like not exercise_id) and
change the Jinja conditional from {% if mcq_parallel %} to {% if allow_mcq_tool
%} (or {% if allow_mcq_tool and mcq_parallel %}) so exercise chats never hit the
else branch that instructs ALWAYS use the tool.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9af9ce9e-1b79-4682-b2d4-41420d65a95d

📥 Commits

Reviewing files that changed from the base of the PR and between 7a0770c and fefa5f0.

📒 Files selected for processing (1)
  • iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2

Comment thread iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2
Comment thread iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2 Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
iris/src/iris/pipeline/chat/chat_pipeline.py (1)

376-376: ⚠️ Potential issue | 🔴 Critical

Use the DTO field name for the exercise title.

The unified exercise DTO exposes the title as name with title only as a serialized alias, so exercise.title can fail during prompt rendering for exercise/text-exercise chats.

🐛 Proposed fix
-            "exercise_title": exercise.title if exercise else "",
+            "exercise_title": exercise.name if exercise else "",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@iris/src/iris/pipeline/chat/chat_pipeline.py` at line 376, The code builds
the "exercise_title" field from exercise.title which can be missing on the
unified exercise DTO; change it to use the DTO's canonical field exercise.name
(i.e., replace exercise.title with exercise.name when constructing the
"exercise_title" value) so prompt rendering uses the correct property; update
any related usages in the chat pipeline where "exercise_title" is populated to
reference exercise.name.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@iris/src/iris/pipeline/chat/chat_pipeline.py`:
- Around line 227-245: The MCQ post-processing (mcq_post_agent_hook) currently
runs before citation and title generation and mutates state.result with the quiz
payload; move the mcq_post_agent_hook call to run after _add_citations and
_generate_session_title but before the final callback.done() so citations/title
generation operate on the original response and the MCQ mixin contract (run
after citations/title and before callback.done) is respected; update the
sequence in chat_pipeline.ChatPipeline (methods: _add_citations,
_generate_session_title, mcq_post_agent_hook, and where callback.done() is
invoked) so mcq_post_agent_hook uses state and mcq_pipeline as before but is
invoked only after title/citation generation.

---

Duplicate comments:
In `@iris/src/iris/pipeline/chat/chat_pipeline.py`:
- Line 376: The code builds the "exercise_title" field from exercise.title which
can be missing on the unified exercise DTO; change it to use the DTO's canonical
field exercise.name (i.e., replace exercise.title with exercise.name when
constructing the "exercise_title" value) so prompt rendering uses the correct
property; update any related usages in the chat pipeline where "exercise_title"
is populated to reference exercise.name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 29b222b8-922e-494f-895e-e1f054d1ca88

📥 Commits

Reviewing files that changed from the base of the PR and between fefa5f0 and 97e08ab.

📒 Files selected for processing (2)
  • iris/src/iris/pipeline/chat/chat_pipeline.py
  • iris/src/iris/pipeline/prompts/templates/chat_system_prompt.j2

Comment thread iris/src/iris/pipeline/chat/chat_pipeline.py
@Senan04
Copy link
Copy Markdown
Author

Senan04 commented Apr 19, 2026

@coderabbitai review
I have addressed all comments and resolved the issues. Please re-evaluate the PR.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 19, 2026

@Senan04 Sure! I'll re-evaluate the PR and provide updated feedback shortly.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@thynguyentumde thynguyentumde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some issues I found:

MCQ provider eagerly runs a Weaviate fetch on every COURSE/LECTURE chat call —iris/src/iris/tools/chat_tool_providers.py:212 lecture_content, _ = retrieve_lecture_content_for_mcq(state.db, course_id, lecture_id=lecture_id). This is called from provide_mcq_generation at provider-registration time, regardless of whether the user actually triggered MCQ. retrieve_lecture_content_for_mcq does a should_allow_lecture_tool DB call plus a db.lectures.query.fetch_objects(...) over all chunks of the course/lecture (see mcq_chat_mixin.py:82-120). Every COURSE/LECTURE chat now pays this cost just to decide whether the MCQ tool is registered. Fix: defer the lecture fetch into the tool's own callable, or move the fetch into prepare_state only when state.mcq_parallel is False and the LLM actually invokes the MCQ tool. A cheap preflight (e.g., does any lecture content exist for the course?) should gate registration; the actual content load belongs inside the tool.

PR description claims a shared ExerciseDTO base class — it doesn't exist —iris/src/iris/domain/data/text_exercise_dto.py:7 and programming_exercise_dto.py:21 both still inherit BaseModel. Per git log, commit 301b202 introduced it; later commits dropped it (f6ca428 was a "Temporary Solution for name/title in exercise_dto.py"). Either reintroduce the base class or update the PR description so reviewers don't expect it.

German TODO + dead pipeline init — chat_pipeline.py:107-109 self.code_feedback_pipeline = CodeFeedbackPipeline(local=local) # TODO: Ungenutzt? Entfernen? code_feedback_pipeline is declared but never used in this class. It's also still in DEPENDENCIES. Remove the field, the dep, and the TODO — or wire it up.

Repeated user_language extraction — chat_pipeline.py:347-349, 434-435, 576-577, plus chat_tool_providers.py:205-207, plus mcq_chat_mixin.py:247-249. Worth a single helper (e.g., get_user_language(dto) -> str) given how often it's repeated.

Defensive checks against fields the DTO declares non-Optional: - dto.user is required (ChatPipelineExecutionDTO.user: UserDTO), but if dto.user shows up in multiple places (chat_pipeline.py:348, etc.). - dto.course is required, but chat_pipeline.py:374-375 does dto.course and dto.course.competencies while line 353-355 just does dto.course.competencies. Pick one.

Verify if these should also be considered for this PR or open a follow-up PR
_CHAT_MODE_STAGES shares mutable StageDTO across modes —status_update.py:272. model_copy() on line 346 is shallow; if StageDTO ever gains nested mutable state (e.g., list), copies will alias. Use model_copy(deep=True) or a stages factory function.

ChatStatusCallback will KeyError for an unknown chat_mode — status_update.py:346. If a future enum entry is added without a stage list, the worker thread crashes silently in Thread. Consider _CHAT_MODE_STAGES.get(chat_mode, default_stages) or an explicit assertion with a clear message.

@Senan04
Copy link
Copy Markdown
Author

Senan04 commented May 7, 2026

Some issues I found:

MCQ provider eagerly runs a Weaviate fetch on every COURSE/LECTURE chat call —iris/src/iris/tools/chat_tool_providers.py:212 lecture_content, _ = retrieve_lecture_content_for_mcq(state.db, course_id, lecture_id=lecture_id). This is called from provide_mcq_generation at provider-registration time, regardless of whether the user actually triggered MCQ. retrieve_lecture_content_for_mcq does a should_allow_lecture_tool DB call plus a db.lectures.query.fetch_objects(...) over all chunks of the course/lecture (see mcq_chat_mixin.py:82-120). Every COURSE/LECTURE chat now pays this cost just to decide whether the MCQ tool is registered. Fix: defer the lecture fetch into the tool's own callable, or move the fetch into prepare_state only when state.mcq_parallel is False and the LLM actually invokes the MCQ tool. A cheap preflight (e.g., does any lecture content exist for the course?) should gate registration; the actual content load belongs inside the tool.

PR description claims a shared ExerciseDTO base class — it doesn't exist —iris/src/iris/domain/data/text_exercise_dto.py:7 and programming_exercise_dto.py:21 both still inherit BaseModel. Per git log, commit 301b202 introduced it; later commits dropped it (f6ca428 was a "Temporary Solution for name/title in exercise_dto.py"). Either reintroduce the base class or update the PR description so reviewers don't expect it.

German TODO + dead pipeline init — chat_pipeline.py:107-109 self.code_feedback_pipeline = CodeFeedbackPipeline(local=local) # TODO: Ungenutzt? Entfernen? code_feedback_pipeline is declared but never used in this class. It's also still in DEPENDENCIES. Remove the field, the dep, and the TODO — or wire it up.

Repeated user_language extraction — chat_pipeline.py:347-349, 434-435, 576-577, plus chat_tool_providers.py:205-207, plus mcq_chat_mixin.py:247-249. Worth a single helper (e.g., get_user_language(dto) -> str) given how often it's repeated.

Defensive checks against fields the DTO declares non-Optional: - dto.user is required (ChatPipelineExecutionDTO.user: UserDTO), but if dto.user shows up in multiple places (chat_pipeline.py:348, etc.). - dto.course is required, but chat_pipeline.py:374-375 does dto.course and dto.course.competencies while line 353-355 just does dto.course.competencies. Pick one.

Verify if these should also be considered for this PR or open a follow-up PR _CHAT_MODE_STAGES shares mutable StageDTO across modes —status_update.py:272. model_copy() on line 346 is shallow; if StageDTO ever gains nested mutable state (e.g., list), copies will alias. Use model_copy(deep=True) or a stages factory function.

ChatStatusCallback will KeyError for an unknown chat_mode — status_update.py:346. If a future enum entry is added without a stage list, the worker thread crashes silently in Thread. Consider _CHAT_MODE_STAGES.get(chat_mode, default_stages) or an explicit assertion with a clear message.

You're right that the MCQ provider runs retrieve_lecture_content_for_mcq on every COURSE/LECTURE chat call regardless of intent. Worth flagging though: this isn't introduced by the refactor. The same eager fetch exists on main today in course_chat_pipeline.py:273 and lecture_chat_pipeline.py:204 (the "non-parallel fallback" tool registration), and provide_mcq_generation is a 1:1 port of that logic — same call site, same conditions, just relocated into the provider registry. -> I think this would be better in another PR

That's true, I introduced a shared ExerciseDTO in an earlier commit, dropped it later on and forgot to update the description. I removed that from the description :D

Fixed: For the corresponding UserDTO on the Artemis side @JsonInclude(JsonInclude.Include.NON_EMPTY) is being used, meaning it will never send null. I changed the UserDTO on pyris side to reflect this. -> When lang_key is missing "en" will be the default, meaning no defensive checks are needed for this and the field can be used directly where needed.

Fixed: No checks for non-optional fields

Fixed: I have used model_copy(deep=True) as suggested. -> afaik the stages need to be changed in a future PR anyways

Fixed: I have added an explicit assertion as suggested

@Senan04 Senan04 requested a review from thynguyentumde May 7, 2026 16:10
Copy link
Copy Markdown

@Predixx Predixx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code lgtm!

Copy link
Copy Markdown
Contributor

@toukhi toukhi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code lgtm. I tested the different Iris chats and everything seems to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants