WorkflowEngine reports node failures by *yielding* `{"type": "error"}`
rather than raising, so complete_stream's generator returns normally and
the except handler never runs. The turn was finalized `status="complete"`
with an empty response.
Live, the client renders an error bubble with a Retry button. On reload
it does not: mapServerQueryToClient only surfaces `metadata.error` for
`failed` rows, so history showed a blank message with no error and no way
to retry. A user hitting this re-sends the same prompt into new
conversations, which is exactly what the 2026-08-01 report shows — nine
blank first messages in seven hours.
Tracks a `stream_error` flag alongside the existing `paused` machinery
and finalizes `failed` when the turn produced no answer, recording the
user-facing message in `metadata.error`. An error arriving *after* output
keeps `complete` so partial text is not discarded; structured answers
count as output too, since they live in `structured_chunks` rather than
`response_full`. The flag is recorded before the pause branches so those
paths cannot lose it.
save_conversation grew a `status` parameter (default `complete`) for the
non-WAL branch, which took no status and so landed on the column default
— the same blank-complete row on a path the WAL fix did not cover.
Title generation now also runs for failed turns: _maybe_generate_title
only regenerates while the name is still the question-prefix fallback, so
skipping it would strand a conversation whose first turn failed with the
raw prompt as its name forever.
logging.py counts a yielded error toward `activity_finished.status`.
These failures previously logged `status=ok` with `answer_length=0`,
which is why user-visible blank answers never appeared in error metrics.
/api/models reports `display_provider` when a catalog YAML sets one
(`foundry`, `azure_foundry`, `cloudflare`), and the builder persists that
string as a node's `llm_name`. The engine passed it straight to
LLMCreator, which only knows the names in PROVIDERS_BY_NAME and raises
`No LLM class found for type <label>`.
That fails the node before any LLM call, so the turn ends in ~60ms with
an empty answer and no tokens generated. It hits the *default* path: the
platform-default model's label is stamped into every newly dragged agent
node and validateWorkflow requires an agent node, so a new user's
untouched workflow could not produce a token regardless of what they
typed. Ordinary chat was unaffected because it resolves the provider from
the model registry and never reads the stored name.
Adds `resolve_dispatch_provider`, which prefers a stored name that is a
real dispatch provider, then the registry lookup, then the parent agent.
Nodes already saved with a label are repaired at run time, so no
migration is needed. The api_key now resolves from the normalized name
too — `get_api_key_for_provider` falls back to settings.API_KEY for names
it does not recognize, which would have sent the deployment key to
whatever endpoint the label happened to select.
Added button to rotate api key. This is required for better UX, now user has to remake agent if key is lost.
A migration is needed to keep track of proper usage + to not leave any orphan entries.
* fix: replace print() with logger in classic_rag.py and encryption.py
Three print() calls bypassed the structured logging system, risking
exposure of rephrased user queries and credential error details to
unmanaged stdout. Replace with logger.debug() / logger.warning() and
add a module-level logger to both files. Also migrate all bare
logging.xxx() calls in classic_rag.py to the module-level logger for
consistency.
* (chore:encryption.py) ruff
---------
Co-authored-by: ManishMadan2882 <manishmadan321@gmail.com>
* docs: fix grammatical parallelism and clean up markdown links in README
- Fixed grammatical parallelism in QuickStart ("build" -> "building" and added "are" to "Five options are available").
- Converted raw HTML tags to clean Markdown links in Project Structure.
- Fixed capitalization for "React widget".
* docs(readme): update extensions description in Project Structure
Project Structure: Updated the extensions/ directory description in README.md to accurately reference Chatwoot and the React widget (removing the outdated Discord bot reference per maintainer feedback).Project Structure Links: Converted raw HTML links to clean Markdown link syntax for better maintainability and readability.QuickStart Grammar Fixes: Corrected grammatical parallelism ("build" $\rightarrow$ "building" and added "are" to "Five options are available").
Address Copilot review on #2600:
- pass a useCallback handler to useOutsideAlerter so the global mousedown
listener isn't torn down/re-added on every WorkflowBuilder render
- remove trailing spaces after {displayName} in AgentPageHeader
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>