The latest from Storytell
Smart AI Model Load Balancing
Smarter Prompt Library with Enhanced Tabs and Favorites
Human-Friendly, Actionable Streaming Error Messages
Gemini 2.5 Model Upgrade
File Processing Status Notifications
Enhanced Text Selection Menu with Disable Option
50-Message Limit for SmartChats™
Collection Auto-Expansion in Sidebar
Improved Handling for Empty Knowledge Base Searches
SmartChat™ Auto-Scrolling
useThreadAutoScroll
hook: This custom hook centralizes the logic for auto-scrolling within SmartChats™. It ensures consistent behavior whenever new messages are received and rendered.threadResponseReceived
) dispatched after a message is fully rendered. This replaces previous timeout-based mechanisms, making the scroll trigger more precise and avoiding issues where scrolling occurred before content was ready.scrollTo
method with the behavior: 'smooth'
option. It targets the full scroll height of the SmartChat™ container, ensuring the latest message is always brought into view gracefully.requestAnimationFrame
: We utilize a double requestAnimationFrame
call before initiating the scroll. This ensures that all DOM updates and layout calculations related to the new message are completed by the browser, leading to more accurate and stable scrolling.Inline Citations
[1]
or [2]
in the sentence, you can click it to jump right to the source. Now, Storytell works the same way: when you get an answer, you can see exactly where every piece of information came from, and check the real text or file it was based on.<citation>
tags wrapped around claims that are supported by user data during answer generation.
On the frontend, citation numbers are mapped to these IDs, allowing for click-to-view source context in a citation panel/drawer.
The citation panel retrieves and formats the relevant data chunk from the user’s assets for display.Citation-Compatible Models
Claude 4 Sonnet Integration
anthropic-claude-4-sonnet
and anthropic-claude-4-sonnet-thinking
, were introduced as selectable Model entries. Each model is assigned its own metadata, including display name, vendor, provider, family tag, ranking scaffold, and capabilities.
ModelSpec
configuration that specifies context window size (180_000
tokens), max output tokens (8_192
), streaming support, and max response time (2 min). All ranking and capability fields are pre-populated or stubbed for future metric updates.
ChatBottomBar.tsx
and TextUnitV1ActionsBar.tsx
) were updated to add menu items for Claude 4 Sonnet and Claude 4 Sonnet Thinking, each with proper iconography and selection logic, ensuring a clear highlight on active selection.
ai.gen.ts
, models.gen.ts
) to include the new models and their associated typings, ensuring strongly typed access throughout the app.
Regenerate Button for Every Response
Chrome Extension Text Selection Pop-Up
Simplified New User Experience & Onboarding for Storytell
useIsUserGettingStarted
, to determine whether the user is in the onboarding/empty state. It checks if the user has any root Collections (that themselves have children) or any SmartChats™ (threads). If not, the UI enters onboarding mode.
TwoColumnLayout
, SideBarCollection
, and CollectionsTop
have been refactored. They now take props (hideSidebar
, showLogo
) that depend on the onboarding state, conditionally rendering those UI elements.
CollectionGettingStartedScreen
component with a clean scaffold: prominent message + upload/asset prompts + “Learn how” link (which opens the documentation at https://docs.storytell.ai/quickstart).
gettingStartedScreenManuallyHidden
has been fully removed, as the onboarding screen is now determined automatically by the user’s data.
ChatTopBar.tsx
, ChatBottomBar.tsx
), toolbar buttons for advanced actions (like slash commands, uploads, mentions) only appear after the onboarding barrier is crossed.
Dedicated Auto-Improve Prompt Section
StIcon
, TbArrowUpRight
), restructuring logic and JSX so that auto-improve is both visually and functionally isolated from the main smart chat prompt flow.
rounded bg-primary text-on-primary flex items-center
).submitPrompt
function if the improved suggestion is available.Improved Mentions with Space Support and Enhanced UX
@tiptap/extension-mention
implementation was replaced by a custom ProseMirror node with an integrated autocomplete handler powered by prosemirror-autocomplete, supporting non-canceling space input.useMentionsState
), with real-time debounce-driven async search to fetch suggestions from both assets and Collections via a dedicated API.prosemirror-autocomplete
as a dependency and cleans up legacy extension and matching code.Storytell can now extract images, tables, and more
Extractor
service, built on a new Go interface (extract.Extractor
), utilizing Google’s Gemini 2.0 Flash model to leverage its multi-modal capabilities for extracting content from various file types.documents.tmpl
, images.tmpl
) to guide Gemini in generating well-formatted, comprehensive markdown and semantically relevant content chunks directly from the source files.PDFSharder
component within the extractor service (using pdftk
) that automatically splits large PDFs into smaller, manageable page groups (e.g., 4 pages each) before sending them to the LLM. This overcomes output token limits and ensures complete processing, with state managed idempotently within the ingestion job.Extract
step, which now handles content extraction, summarization, and chunking previously done by multiple separate steps (like Tika/PDF processing and Summarize).extractor
service to Kubernetes using Helm charts, updated CI/CD workflows for building and deploying the service, and configured necessary GCP permissions and service accounts.pkg/go/domains/assets/extract
package, defining an Extractor
interface. The primary implementation, LLMExtractor
, leverages the genai
Go SDK to interact with the Gemini 2.0 Flash model via its multi-modal API (genai.NewContentFromURI
). Extraction logic is guided by Go templates (documents.tmpl
, images.tmpl
) specific to content types (documents vs. images).A new standalone extractor
microservice (Go, Docker, Kubernetes via Helm) was created. This service hosts:PDFSharder
: An HTTP endpoint (/v1/pdf-shard
) that accepts a signed URL for a PDF, downloads it, uses pdftk-java
(specifically version 3.2.2-1
from Debian Bullseye) to split the PDF into chunks (currently 4 pages each), and uploads these shards to a temporary GCS location ($organizationId/tmp/$assetId-$shardNum.pdf
).PDFConvertor
: An HTTP endpoint (/v1/pdf-convert
) that accepts a signed URL for a supported non-PDF file (initially .docx, .pptx), downloads it, uses libreoffice --headless --convert-to pdf
to create a PDF version, and uploads the converted PDF to GCS.pkg/go/domains/assets/ingest/ingester.go
) was modified:Extract
step (process_extract.go
) was added for content types supported by LLMExtractor
(PDF, PNG, JPEG, WEBP, and convertible types like DOCX, PPTX).conversionRequired
. If so, it calls the PDFConvertor
endpoint on the extractor
service.PDFSharder
endpoint. The shard details (extract.PDFSharded
struct) are stored base64 encoded in the job’s assets (AssetKeyPdfShards
).Extract
step iterates through the PDF shards (or processes the single file/shard if not sharded), generating signed URLs for each shard/file and calling p.extractor.Extract
with the appropriate extract.ExtractionRequest
(containing the signed URL and content type).processExtraction
helper function handles the call to p.extractor.Extract
, appends the resulting markdown, generates search.Chunks
with sequential IDs, performs embedding, stores embeddings, and updates Collections. It also extracts metadata (display name, summary) from the first shard’s output.extract.PDFSharded
struct and saved back to job assets after each shard to ensure idempotency.ErrTokensExceeded
error from the extractor is handled specifically, causing a fatal job error.PDF
(which used Tika) and the separate Summarize
step are bypassed or removed for these file types, as extraction and metadata generation are now handled within the Extract
step.helm/charts/extractor
) for deploying the extractor
service.terraform/live/...
) to provision the Helm release, configure service accounts (extractor.serviceAccountName
), permissions for GCS signed URL generation/access, and secret management..github/workflows/ci-*.yml
, deploy-*.yml
) to build the extractor
Docker image (using services/extractor/Dockerfile
) and include it in deployment steps.Taskfile.yml
, magefile.go
) for local development and CI builds.Top Banner for Chrome Extension Promotion
Auto-Show and Scroll for Hidden Collections
Advanced Reasoning Support for AI Models
Add OpenAI 4.1 Family to Dynamic LLM Router
Automatic Prompt Improvement
@[id]"Name"
) are preserved exactly as they were input, maintaining compatibility with other Storytell features.
PromptAutoImprove.tsx
component that monitors the editor state through TipTap’s update events. The system employs a 1.5-second debounce mechanism to detect when users have paused typing, at which point it triggers the enhancement process for prompts containing at least 3 words.
/controlplane.PromptEnhancer
endpoint with a type parameter of "auto_improve"
. This endpoint processes the raw prompt through specialized instruction templates defined in Go embed files (templates/auto_improve_prompt.md
). These templates guide the backend LLM to analyze the prompt against core enhancement principles including context enrichment, structural optimization, clarity and precision, role perspective definition, and brevity.
prompt_enhanced.content
array containing the suggested improvement. Upon receiving this response, the UI transitions from the “Improving your prompt” state to displaying the suggestion with action buttons.
Prompt Library
LLaMA 4 Scout Now Available for Manual Selection
Enhanced Error Streaming for Improved Client Interaction
expectedEncoreVersion
v1.46.16.PromptBuilderV2.Process()
enables errors to be streamed instead of causing abrupt failures.ErrStreamedToClient
error type in processes within PromptBuilderV2
and MessagePromptV2
.expectedEncoreVersion
, addressing errors seamlessly across updated platform versions.Content Upload Experience with the Prompt Bar
Why Storytell Link Added to Navigation Bar
Expanded Language Support - Chinese Simplified and Traditional
pkg/ts/core/src/lib/data/lanugagesByPopularity.ts
file. This involves adding the appropriate language codes (“zh_CN”, “zh_TW”) and names (“Chinese - Simplified”, “Chinese - Traditional”) to the language configuration.Link Sharing for Collections
share_public_token
which is a char(68)
) and stores it in the controlplane.dat_collection_link_shares
table. This token is then used to construct a shareable URL.controlplane.create_collection_secret_share
function checks if the acting user has the required permission on the Collection before creating the share record. Access is granted through the AcceptCollectionSecretLinkToken
function in curator_core_accept_collection_secret_link_token.go
after validating the token and creating appropriate Collection grants.services/controlplane/migrations/50_collection_secret_link_sharing.up.sql
migration creates the controlplane.dat_collection_link_shares
table to store the secret link details. It also creates the function controlplane.create_collection_secret_share
to create the new Collection share recordAcceptCollectionsSecretLink
endpoint (endpoint_collection_secret_link_accept.go
) allows users to join a Collection using a secret link. The DeleteCollectionsSecretLink
endpoint (endpoint_collection_secret_link_delete.go
) allows Collection owners to revoke a secret link, invalidating it for future use.GetCollectionAccess
function in curator_core_get_collection_access.go
redacts the email address to only show the domain.controlplane.dat_collection_link_shares
table stores information about the shared link, including the token, Collection ID, sharing user, and permissions.AcceptCollectionsSecretLink
(POST /v1/collection-secret-token/:publicToken): This endpoint handles the acceptance of a secret link token. It verifies the token, retrieves the associated Collection share record, and grants the user access to the Collection.DeleteCollectionsSecretLink
(DELETE /v1/collection-secret-token/:tokenID): This endpoint revokes a secret link by deleting the corresponding record from the controlplane.dat_collection_link_shares
table.AcceptCollectionSecretLinkToken
(curator_core_accept_collection_secret_link_token.go
): This function validates the secret link token, retrieves the Collection share record, builds collection grants, and grants access to the user.DeleteCollectionSecretLinkToken
(curator_core_delete_collection_secret_link_token.go
): This function deletes a secret link token and its associated grants.GetCollectionAccess
(curator_core_get_collection_access.go
): This function checks if the current session user has access to the Collection via a secret link and redacts the email.VerifyShareToken
function is used to ensure that the token is well-formed before performing any expensive operations.services/controlplane/test/integration/collection_share_test.go
file contains integration tests that verify the functionality of the secret link sharing feature, including creating, accepting, and deleting secret links.Map-Reduce Architecture for Large Language Models
{{bucket}}/{{organization}}/debugged/prompt/{{messageId}}.json
.Gemini 2.0 Pro Model
Retry Button for Failed File Uploads
YouTube Scraping Integration
crawl_strategy_youtube.go
to utilize ScrapingBee for retrieving video page content. This not only provides a more reliable method to fetch transcripts but also ensures a robust fallback in case captions are missing. The enhanced workflow minimizes errors and improves data completeness.
pkg/go/domains/assets/ingest/web/scrapingBee.go
, was introduced. This module handles HTTP requests to the ScrapingBee API, forwarding necessary headers and managing proxy configurations. It abstracts the complexity of the scraping process to provide a simple interface for content extraction.
go.mod
and unused dependencies removed from go.sum
. Configuration files now require a ScrapingBee API key, ensuring that the setup is streamlined for the new integration.
RenderJS
and PremiumProxy
to ensure complete rendering of dynamic content. The integration allows header forwarding, meaning custom HTTP headers can be added to mimic browser behavior—essential for bypassing common scraping pitfalls. After receiving the response, the module processes the HTML to extract essential metadata like the title and description. Additionally, the transcript extraction logic uses XML parsing to decode caption data. This shift not only replaces the older Firecrawl implementation (which has now been fully removed) but also makes the system more robust by combining effective error handling, improved dependency management, and a simplified code architecture.New way to override LLM Router aka the 'Jeremy' feature
Chat Thread Attachments
WithAttachments
option function. With this change, developers can now include attachments when sending a text message prompt. The process is as simple as adding an “attachments” parameter to your API call, making the integration more flexible.
addAttachments
method that processes attachments alongside other prompt data. This method ensures that attachment content is properly prioritized and accounted for within the overall token budget, so the response generation process remains efficient even when supplemental data is included.
knowledgeBase
, includeTrainingData
, and onlyTrainingData
methods). They now factor in attachments when constructing the final prompt. This ensures that if attachments are provided, they are integrated optimally without surpassing budget limits.
stid
package to uniquely identify each attachment.attachments
was added to the Prompt struct.WithAttachments
option function allows developers to easily add one or more attachment objects during the creation of a prompt.addAttachments
method is responsible for processing attachment data. It ensures that the content of each attachment is trimmed if necessary (using a preset token budget), validates that required fields (like title, source, and extracted content) are provided and not empty, and automatically rejects or truncates attachments that exceed predefined size limitations.Enhanced the Prompt ELI5 and Age-Based Explanations
responsePromptsData
to set the correct prompt based on the user’s selection. Several new cases were added, each mapping to a different explanation style. The event handler calls the appropriate function (explainLikeImTwelve
or explainLikeImSixteen
) after retrieving the text input, ensuring that the response reflects a middle school or high school level of explanation.submitPrompt
have been added that leverage the enhanced responses from responsePromptsData
. The component uses conditional logic to direct the input text through either the explainLikeImTwelve
or explainLikeImSixteen
transformation functions, ensuring that the text is correctly formatted for the target audience.responsePromptsData
configuration to support multiple age-based explanation templates. In addition to the ELI5 template, prompt templates for middle school (explainLikeImTwelve
) and high school (explainLikeImSixteen
) have been added. These templates include specific instructions to ensure that every generated explanation is tailored to its intended audience.responsePromptsData
file now includes new functions that wrap the input text in detailed instructions. These functions provide layered explanation prompts that guide the response generator on how to elaborate the explanation based on the selected age group. The templates use string interpolation and clearly defined language guidelines to ensure consistency in tone and detail for each audience.
Updated Homepage Card Order & De‑silo Teams Navigation Link
Allow up to (30) tabs on an XLS sheet
pkg/go/domains/assets/tabular/xls.go
. The key change was updating the constant (initially set to 20) to allow up to 30 sheets. The change directly addresses feedback from DROdio, ensuring that XLS files with many tabs are processed without upload failures, although caution is advised regarding very large sheets (each exceeding 1,000 rows) which could introduce challenges in the summarization stage.Allow spaces when mentioning files or Collections
Remove Relevancy from Storytell Responses
Magic Link Dark Mode UI Text Visibility
Resize Left Sidebar to Show More Chats
Scroll to Collection when clicking it's breadcrumb
Improved `Not Found` Messaging
Add Claude 3.7 to the LLM router
Download Markdown Tables as CSV
<thead>
and <tbody>
sections of markdown tables. It parses header and row data into a structured array, ensuring that all text is properly escaped to conform to CSV standards.
<thead>
and <tbody>
elements. It then extracts header cells and row data, mapping them into a string[][] format. Special characters are properly escaped using CSV conventions. The resulting CSV string is wrapped into a Blob with MIME type “text/csv;charset=utf-8”, and a temporary anchor element is generated to programmatically trigger a download, providing a seamless export experience within Storytell.Auto-Scroll for Active Collection in Sidebar
Share Collections based on Email Domain
Show Breadcrumbs for Collections in the Search Bar
Improve Performance When Listing Assets Within Collections
services/controlplane/domains/curator/collectionsSQL/asset_col_queries.sqlsqlc.generated.go
has been optimized.GetCountAssetsByCollectionID
, has been added in services/controlplane/endpoint_collection_get_count_assets_by_collection_id.go
.GetAssetsByCollectionID
function in services/controlplane/domains/curator/curator_core_get_assoc_assets.go
was modified to include sub-collections based on the IncludeSubCollections
parameter.Batch Upload Websites
WebContentUpload.tsx
has been modified to allow for multiple URL inputs. The CrawlURL
function in the client API is used to initiate the scraping process for each URL.Search for Collections and Assets
Storytell Response Breakdown
Delete SmartChats™
Enhanced `Improve It` User Experience
LLM Response Timeout Management
context.WithTimeout
with 60-second duration for main LLM callsdefer cancel()
Add Llama and DeepSeek Models to the LLM router
Use Deepseek
or Use Llama
to their queries, though neither is yet embedded in the LLM router. Check this page on how to manually override the LLM routerUse Deepseek
or Llama by adding Use Llama
to their prompts.Use Deepseek
and Use Llama
).Mention Collections and Files
New Signup and Login Page
New Collection Screen Layout
Onboard Gemini 2.0 Flash model from Google
One-click `Improve It` Button
Onboard o3-mini Model from OpenAI
Ability to Edit and Delete Assets
CollectionAssetTable
, EditAssetModal
, and DeleteAssetModal
that provide users with interfaces to edit asset details or delete assets.CollectionAssetTable
and related CSS ensure that the new editing and deletion buttons are well integrated into the existing design, making it intuitive and responsive on various devices.
Manage and Control Access for Collections and Chats
Ability to download the original file from Stored Assets
Replicate the Storytell Website Home Page to Storytell.ai
XLS → CSV Conversion
CRUD Function for Collections
Address Non-Tabular Data in CSV Files
CSV Content Classification
Categorization for Comparative Queries in LLM Router
PromptCategories
list. This list contains the categories identified by the LLM, which are used to guide the model selection process. If the router cannot define a specific category, it assigns a generic category to ensure that the query is still processed effectively.PromptCategories
list. This list helps in guiding the model selection process by providing identified categories for the prompt.Web Scraper MVP
youtube-transcript-api
, to download YouTube videos and their transcripts. In its first generation, the scraper integrates the Firecrawl API to perform crawling and scraping tasks. Here’s a deeper look into its technical components:HIPAA certification
Use RAW Prompts for Suggestion Generation
Refining Prompt Transformation for Friendlier Interactions
Exclude CSV Results from Search Routing
Improving Search System Visibility to Address Customer Issues