Skip to content

[pull] main from danny-avila:main#65

Merged
pull[bot] merged 5 commits intoinnFactory:mainfrom
danny-avila:main
Apr 19, 2026
Merged

[pull] main from danny-avila:main#65
pull[bot] merged 5 commits intoinnFactory:mainfrom
danny-avila:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 19, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

* 🔊 fix: warn when `trigger.type` is unrecognized

`shouldTriggerSummarization` silently returned `false` whenever the
configured `trigger.type` was not one of the three it implements
(`token_ratio`, `remaining_tokens`, `messages_to_refine`). That turned
any upstream schema/SDK drift into a silent no-op — summarization just
never fired, with no signal to the operator.

Emit a one-time `console.warn` per unrecognized type so the
misconfiguration surfaces in logs without spamming every agent turn.

Behavior is unchanged for all valid trigger types and for the
no-trigger-configured default.

* 🧹 fix: bound the unrecognized-trigger dedup set

Per Codex review: the dedup `Set` for warned trigger types was
process-global and grew unboundedly. Consumers that thread dynamic or
user-provided values through `trigger.type` could accumulate unique
keys in long-lived workers — a minor but real memory vector.

Cap the set at 32 entries and evict the oldest on overflow (Set
preserves insertion order, so this is FIFO-ish). 32 is well above the
handful of typos a legitimate deployment would ever see, and the dedup
contract still holds: we never warn twice for a type that is currently
in the set.
#109)

* 🔊 fix: include provider, model, and HTTP status in summarization error logs

When summarization fails, host applications (e.g. LibreChat's default console
formatter) frequently strip metadata from the winston info object, leaving
users with only a generic "Summarization LLM call failed" message — no
indication of which provider/model misbehaved or why.

Fold the critical bits (provider/model label and HTTP status when present)
into the log message string itself so they survive any downstream formatter.
Keep the structured metadata bag intact for JSON/structured backends. Apply
the same treatment at each summarization error site (primary failure,
fallback failure, metadata-stub fallback).

* 🛡️ fix: guard nullish throws, attribute fallback failures to the right provider

Two issues surfaced by code review on the initial logging pass:

1. `describeProviderError` cast `err` to a non-nullable object and read
   `.status`/`.statusCode`/`.response?.status`; TypeScript's no-unnecessary-
   condition rule then stripped the optional chaining on `errObj`. If a
   provider throws `null` or `undefined` (both legal throw targets in JS),
   the status extraction would itself raise `TypeError` and mask the
   original summarization failure. Extract status through a dedicated
   helper with an explicit `err == null` guard so the intended metadata-stub
   recovery path is preserved for any thrown value.

2. The fallback-exhausted warning reused the primary provider/model label
   for the error thrown out of `tryFallbackProviders`. That error actually
   comes from the last attempted fallback and is not necessarily the
   primary integration. Introduce `describeFallbackError` which labels the
   log with the list of fallback providers attempted, so operators are
   pointed at the right deployment when diagnosing incidents.

Reviewed-by: Codex (P1 + P2 findings on PR #109).

* 🛡️ fix: defend against malformed fallback config in error-logging path

`describeFallbackError` previously trusted that every element in the
`fallbacks` array was a non-null object with a `provider` field. If
runtime config is malformed (null/undefined entries, missing provider),
reading `.provider` from inside the surrounding `catch (fbErr)` block
would throw a fresh TypeError, promoting a recoverable summarization
failure into an uncaught exception and blocking the metadata-stub
fallback.

Widen the parameter to `ReadonlyArray<unknown>`, filter out malformed
entries, and fall back to `no-fallbacks` label when none remain. The
logging path is now total on any input.

Reviewed-by: Codex (P2 finding on PR #109, commit 8b6d27a).

* 🛡️ fix: validate fallback list shape before mapping in error formatter

`describeFallbackError` previously assumed `fallbacks` was an array because
the type signature said so. In practice the value originates from
`clientConfig.clientOptions` via an unchecked `unknown` cast, so a
malformed runtime config (e.g. a string with truthy `length`) would reach
`.map(...)` and throw `TypeError: fallbacks.map is not a function` —
escaping the surrounding `catch (fbErr)` and blocking the metadata-stub
recovery path.

Widen the parameter to `unknown`, coerce to an empty array when it isn't
one. Also coerce the call site's `fallbacks` binding with `Array.isArray`
so `tryFallbackProviders` doesn't see a non-array either.

Reviewed-by: Codex (P2 finding on PR #109, commit dc5456e).
Adds a `validateEdgeAgents()` check in the `MultiAgentGraph` constructor
that throws a descriptive error when any edge (on `from` or `to`) points
at an agent not present in `agentContexts`.

Without this guard, `StateGraph.compile()` later throws the opaque
`Found edge ending at unknown node "<id>"` error that gives callers no
indication of why — this was the surface error from LibreChat's
#12726 where the host passed `edges` into a multi-agent run without
also loading the sub-agents. The new error explicitly instructs callers
to include every referenced agent or filter orphaned edges upstream.
Move `initializeModel` inside the try/catch in `executeSummarizationWithFallback`
so that errors like `Unsupported LLM provider: <name>` are surfaced through the
`log('error', ...)` path and fall through to the metadata-stub fallback, instead
of bubbling up silently.

This is the defense-in-depth half of the fix for the LibreChat Discussion #12614
report: when a caller forwards an unrecognized summarization provider name
(e.g. a custom-endpoint label), the error is now observable in operator logs
rather than only the client UI.
@pull pull Bot locked and limited conversation to collaborators Apr 19, 2026
@pull pull Bot added the ⤵️ pull label Apr 19, 2026
@pull pull Bot merged commit b749483 into innFactory:main Apr 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant