Passing OpenRouter's metadata filters does not prove a model can complete a
turn through this harness, so dead-but-advertised models kept reaching users
and failing mid-stream. A new model_compatibility table holds one verdict per
model, a weekly Celery sweep re-probes stale entries, and catalogue
generation reads the blocked ids back so those models are never offered.
Also excludes :batch variants, which advertise full chat metadata and then
reject completions outright.
Auto-pin now falls through to Auto when an explicitly selected global config
is absent from the current worker's catalogue. Returning it handed
load_llm_bundle an id it could not resolve, ending the turn with SERVER_ERROR
on one of the four uvicorn workers while the identical request succeeded on
the others. Catalogue refresh also re-materializes GLOBAL_MODELS, which
previously kept its boot snapshot until restart.
On the web side a single dropped connection surfaced as one toast per
in-flight query and dozens of PostHog exceptions, with no retry button.
Network errors now share a toast id, are deduped per endpoint before capture,
carry host and online context, and count as retryable.
Consolidates the model filter helpers duplicated between the model list and
OpenRouter services into openrouter_model_normalizer, renames OoxmlDefect to
OoxmlError, and includes a ruff format and import-order pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Updated `ArtifactCard` to ensure proper overflow handling and prevent layout issues with long text.
- Adjusted styles in `ArtifactsLibrary` for better responsiveness and to manage overflow in the grid layout.
- Added `selectedCardToolCallId` to the artifact panel state for improved tracking of selected artifacts.
- Updated `openArtifactPanelAtom` to accept `selectedCardToolCallId` when opening the panel.
- Modified `ArtifactCard` component to pass `toolCallId` when opening the artifact panel, ensuring correct selection highlighting.
- Refactored `scroll-to-artifact` logic to utilize the new `selectedCardToolCallId` for better artifact navigation.
- Adjusted styles in the artifact card to visually indicate the selected state.
- Introduced `useArtifactDeepLink` hook to manage deep linking for artifacts in chat.
- Updated `useSyncChatArtifacts` to return loading states and artifacts for better UI feedback.
- Added `ThreadMessagesSkeletonBody` component for improved loading experience in the thread view.
- Refactored `ArtifactCard` to support deep linking and streamlined artifact display logic.
- Removed unused media viewer dialog component to simplify the artifacts library UI.
- Introduced a new `DocumentTypeFilterList` component for improved filtering of document types.
- Added search functionality to filter document types based on user input.
- Implemented scroll position tracking to enhance user experience in the filter list.
- Updated `DocumentsFilters` to integrate the new filtering component and handle mobile responsiveness.
- Refactored existing state management for clarity and efficiency.
- Introduced support for displaying an `ArtifactFormatIcon` when the document type is "ARTIFACT".
- Updated the `FORMAT_META` to include a new presentation-only key for artifacts, enhancing the visual representation in the UI.
- Ensured consistent handling of document types across the application.
- Added `document_id` to artifact listing for improved metadata association.
- Introduced `ArtifactFormatIcon` and `ArtifactFormatLabel` components for better visual representation of artifact formats.
- Updated various components to utilize new format handling, ensuring consistent display across the application.
- Refactored artifact-related schemas and hooks to accommodate new format data.
- Enhanced unit tests to cover new functionality and ensure robustness.
- Updated `ArtifactViewerContent` to conditionally display download filename based on workspace validity.
- Added `refetchOnWindowFocus` option to artifact query for improved data freshness.
- Replaced `documentStatus` with a Zod enum for `indexing_status` in artifact schemas.
- Refactored `collectArtifacts` to return `ArtifactCandidate` and adjusted related functions for better artifact management.
- Removed unused imports and streamlined the `ArtifactRow` component for clarity.
Rename podcasts -> podcast_runs and treat the run row as job state
only: delivered audio and its markdown live in the Artifact, so the
row drops storage_backend/storage_key/file_location and gains
artifact_id. mark_ready commits status and artifact_id atomically,
preserving the READY <-> artifact_id invariant that Zero publishes.
Public shares stream audio through the artifact content route and get
artifact_id + workspace_id injected at snapshot time; the authenticated
player and library read artifactId from Zero. Retire the legacy
authenticated stream route, the podcast storage helpers, and the REST
list endpoint.
- Updated `list_artifacts` to accept an optional `thread_id` parameter for filtering artifacts by thread.
- Modified the query to conditionally include the `thread_id` in the selection criteria.
- Enhanced frontend components to support thread-specific artifact fetching and display.
- Added unit tests to verify the new functionality for scoping artifacts to a specific thread.
Video now delivers into an Artifact like image and podcast. The run row
becomes a lifecycle record and the Remotion payload lives in the Artifact.
- run carries artifact_id; the tool returns artifact_id + workspace_id and
the frontend renders from the Artifact
- public shares serve video and slide audio through artifact-scoped routes
behind the snapshot allowlist, replacing the broken audio_file path
- purge_document_blobs collects slide audio storage keys so deleting a video
Artifact no longer orphans them
- backfill_video_artifacts.py converts legacy rows and repoints chat and
snapshot payloads (run before the slim migration)
- migrations: 179 adds artifact_id (expand); 180 renames the table to
video_presentation_runs, drops slides/scene_codes, adds error, and
publishes to Zero (contract). 180 aborts if any delivered run still lacks
an Artifact, so the backfill can't be skipped
- publish video_presentation_runs to Zero so in-flight and failed runs reach
the library by push; retire the legacy REST routes, schema, and poller
- Added a new `SpreadsheetGrid` component to render Excel sheets using `react-data-grid`.
- Enhanced the viewer to display worksheets with dynamic column and row generation.
- Updated loading and error handling messages for better user experience.
- Refactored existing table structure to utilize the new grid component for better performance and styling.
- Added state management for pending folder deletion and deletion status.
- Refactored folder deletion logic to include a confirmation dialog before proceeding with the deletion.
- Integrated alert dialog to notify users of the deletion action and its consequences.
generate_image now bills, calls the provider once and persists through
save_artifact, with the generation parameters and revised prompt kept as
provenance. The ImageGeneration model, its routes, schemas, RBAC permissions
and per-image access tokens are gone, along with the frontend service and
types; viewers fetch the primary file through the artifact manifest.
Shared chats keep working: the snapshot stores the artifact ids its messages
reference and a public route serves only those, so a token grants the thread's
own artifacts rather than the workspace's.
- Updated docker-compose.dev.yml to include a persistent pnpm store for caching dependencies.
- Modified Dockerfile to reconcile node_modules with the lockfile before starting the development server, ensuring consistent dependency management.
Comments described the cutover phases rather than any constraint the code
can't show. Keep only the conditions a reader needs (public shares, media
with no Artifact row) and let the slide-key filter speak for itself.
Split artifactId vs legacyEntityId in the chat collector, return artifact_id
from generate_image, and align roster tests with the current filename shape.