Skip to content

Release 0.59.5#3102

Merged
odlbot merged 8 commits into
releasefrom
release-candidate
Mar 25, 2026
Merged

Release 0.59.5#3102
odlbot merged 8 commits into
releasefrom
release-candidate

Conversation

@odlbot
Copy link
Copy Markdown
Contributor

@odlbot odlbot commented Mar 25, 2026

Chris Chudzicki

renovate[bot]

Shankar Ambady

ChristopherChudzicki and others added 8 commits March 25, 2026 08:03
Now that the programs API returns parent program info, display the
bundle upsell on program-as-course pages the same way we do on
course pages.

Closes #10644

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update qdrant point id keys (#2990)

* unify key generation for point ids

* fix tests

* adding platform to vector key

* fix tests

* fixing other methods requiring point key

* fix point key

* fixing test

* account for platform=None

* Vector Search: hybrid search (#3060)

* adding sparse encoder util

* adding sparse encoder setting

* add sparse enc

* adding sparse hash encoder

* adding scikit-learn

* fix sparse encoder

* fix topic embedding'

* fix default vectorizer name

* adding cloud inference capability

* adding openai api key to options dict

* fix limits

* docstring updates

* adding test

* some optimizations

* fixing limit for prefetch queries

* hide hybrid search behind posthog feature flag

* scale prefetch with offset

* fix yield return

* fix sparse hash threshold calculation

* switching hybrid search to be a url param

* remove search params from groupby

* adding cache decorator to sparse encoder

* fix test

* fix test

* add default encoding name

* fix tests

* fix stop_words param

* adding test for hybrid flag and group_by

* pinning tokenizer to None for tests

* fix sparse embedding when searching

* temporarily pin to _V2 settings for the cutover (#3077)

* set max prefetch for hybrid searches

* switch to settings for prefetch multiplier

* Update vector_search/utils_test.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
* bump client

* bump client

* fix verified program enrollment API call to match updated client

The API changed from program_id path param to request_body array.
Update DashboardCard and the enrollment test to use the new signature.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add ancestorPrograms prop for verified enrollment across program hierarchy

ModuleCard now accepts ancestorPrograms (array of {readable_id, enrollment_mode})
instead of a single programEnrollment. When any ancestor has verified
enrollment_mode, it calls createVerifiedProgramEnrollment with all ancestor
readable_ids. This enables verified enrollment for courses nested inside a
program-as-course whose grandparent program has the verified enrollment.

ProgramAsCourseCard passes ancestorPrograms through to ModuleCard.
EnrollmentDisplay assembles the array: home dashboard passes the parent
program-as-course; program dashboard passes both parent and grandparent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix review issues: deduplicate render paths, move AncestorProgram type, fix legacy test

- Extract renderResource() in EnrollmentExpandCollapse to eliminate
  duplicated map callback between shown/hidden resource lists. This also
  fixes the missing ancestorPrograms prop in the hidden resources path.
- Move AncestorProgram type from ModuleCard to helpers.ts (shared domain
  concept, not card-specific).
- Fix DashboardCard.test.tsx verified enrollment URL to match new API
  signature (courserun_id only, no program_id in path).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* remove unnecessary factory overrides in enrollment display test

Use factory defaults instead of hardcoded titles and spreading
throwaway factory instances. Assert on the factory-generated values
instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* use EnrollmentModeEnum from API client instead of local redefinition

Replace the hand-rolled EnrollmentMode const in ModuleCard with
EnrollmentModeEnum from @mitodl/mitxonline-api-axios. Use the same
type for AncestorProgram.enrollment_mode in helpers.ts for type safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* simplify ancestor program props: ProgramAsCourseCard assembles IDs and verified flag

Replace ancestorPrograms array with a cleaner design:
- ProgramAsCourseCard accepts optional ancestorProgramEnrollment (the
  grandparent enrollment, singular) and assembles parentProgramIds +
  useVerifiedEnrollment from courseProgram.readable_id + ancestor
- ModuleCard accepts simple parentProgramIds (string[]) and
  useVerifiedEnrollment (boolean) — no enrollment objects needed
- Remove AncestorProgram type from helpers.ts (no longer needed)

This fixes the bug where ancestorPrograms was only populated when
courseProgramEnrollment existed — the exact case we don't need it.
Now the parent readable_id always comes from courseProgram (the program
detail object), which exists regardless of enrollment status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add some docstrings, minor refactor

* remove hardcoded IDs and titles from ProgramAsCourseCard tests

Auto-generate program and module IDs inside setupCardData instead of
requiring callers to pass arbitrary values. Assert on factory-generated
values (cardData.courseProgram.title, cardData.moduleCourses[0].title)
instead of hardcoded strings. Add docstring to setupCardData.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* simplify req_tree ordering test to reverse moduleCourses instead of req_tree

The test verifies display order follows req_tree, not the moduleCourses
array order. Reversing the moduleCourses input is simpler and more
directly tests the behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* improve test quality: add integration test, remove unnecessary overrides, use invariant

- Add integration test for grandparent verified enrollment flowing
  through EnrollmentDisplay -> ProgramAsCourseCard -> ModuleCard,
  asserting both parent and grandparent readable_ids in POST body
- Split verified enrollment test into two: regular course (one program
  ID) and program-as-course module (two program IDs)
- Extract setupProgramDashboardVerifiedEnrollmentScenario helper (API
  setup only, no render)
- Remove unnecessary grades: [] factory override in ProgramAsCourseCard
  tests
- Remove hardcoded IDs and titles in EnrollmentDisplay verified
  enrollment test
- Replace card\! non-null assertions with invariant() for clearer
  failure messages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix typo: Courslike -> Courselike in docstring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add isVerifiedEnrollmentMode helper

* use isVerifiedEnrollmentMode in legacy DashboardCard

Replace local EnrollmentMode constant with the shared
isVerifiedEnrollmentMode helper from @/common/mitxonline, consistent
with ModuleCard and ProgramAsCourseCard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix typo

* update client

* bump client

* invalidate program enrollments, too

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

OpenAPI Changes

Show/hide 2 changes: 0 error, 0 warning, 2 info
2 changes: 0 error, 0 warning, 2 info
info	[new-optional-request-parameter] at head/openapi/specs/v0.yaml	
	in API GET /api/v0/vector_content_files_search/
		added the new optional 'query' request parameter 'hybrid_search'

info	[new-optional-request-parameter] at head/openapi/specs/v0.yaml	
	in API GET /api/v0/vector_learning_resources_search/
		added the new optional 'query' request parameter 'hybrid_search'


Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

Comment thread vector_search/utils.py
Comment on lines +94 to +98
if any(dense_vector):
point_vector: dict[str, models.Vector] = {
dense_vector_name: dense_vector,
sparse_vector_name: sparse_vector,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The points_generator function causes a TypeError when using QdrantCloudEncoder because it attempts to iterate over a non-iterable Document object returned by the encoder.
Severity: CRITICAL

Suggested Fix

In points_generator, before calling any(dense_vector), add a check to ensure dense_vector is an iterable type (like a list or tuple). If it is a Document object, extract the vector from it or handle it appropriately. Alternatively, modify QdrantCloudEncoder to return a standard vector format consistent with other encoders.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: vector_search/utils.py#L94-L98

Potential issue: In the `points_generator` function, the code calls `if
any(dense_vector):` assuming `dense_vector` is an iterable list of floats. However, when
`QdrantCloudEncoder` is configured as the dense encoder, it returns a non-iterable
`qdrant_client.models.Document` object for `dense_vector`. This mismatch causes a
`TypeError: 'Document' object is not iterable` at runtime, which will crash any
embedding operations using this configuration.

Did we get this right? 👍 / 👎 to inform future reviews.

@odlbot odlbot merged commit b49ad93 into release Mar 25, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants