You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the summary endpoint is unreachable or the model isn't loaded, the summary is lost permanently. The transcript survives (it is the canonical artifact and always written first), but the -summary.md never appears, and nothing ever tries again — the user has to notice the failed notification and manually re-run Parley summarize -i <transcript>.
This is not hypothetical. Two real recordings lost their summary to endpoint failures:
The realistic everyday cases are simpler still: LM Studio isn't running, the model was unloaded to free VRAM, or the machine was on battery/asleep when a recording finished. A meeting summary is exactly the thing a user assumes happened and only discovers is missing days later.
Why this fits the product
The summary is a derivative — the transcript is canonical — so a failure is recoverable in principle. Nothing currently acts on that. Given the airgapped, courtroom-grade framing, a silently-missing derivative is a smaller failure than a corrupt transcript but still a gap the system already has enough information to close on its own.
Sketch
Persist the intent, not just the failure. On a failed summary, record a pending marker (e.g. ~/Library/Application Support/Parley/pending-summaries.json, or a field in the session state) holding the transcript path, the failure kind, and an attempt count.
Retry on the signals that actually mean "it might work now":
app launch (covers "the Mac was asleep / LM Studio wasn't up yet")
endpoint reachability regained — a cheap probe already exists in LMStudioSummaryProvider.fetchLoadedState() (/api/v0/models, 5 s timeout)
a bounded backoff while the app is running
Only retry what is worth retrying. The URLError mapping added alongside #173 makes the failure kinds distinguishable, which is what makes this safe:
Quiet — do not re-notify per attempt. One notification when a pending summary eventually succeeds is useful; a notification per retry is how the whole notification channel gets muted (the same reasoning as gotcha bug: CLIHandler --debug may crash on exit if /usr/bin/log failed to launch #62 on the capture-anomaly label).
Bounded — give up after N attempts or M days and say so once, rather than retrying a dead endpoint forever.
Batched — several pending transcripts should drain in order, not race.
Acceptance sketch
Kill LM Studio, record a short meeting, confirm the transcript is written and a pending marker exists.
Start LM Studio, and without any user action the summary appears (on launch, or on the reachability probe).
Re-running the retry with a summary already present is a no-op.
A permanently bad endpoint stops retrying and reports once.
Related
#173 (timeout, fixed), #157 (summary quality), #37 (Apple Intelligence provider — a second provider makes the "don't silently switch providers" constraint more important, not less).
Part 2: prevent the failure, not only recover from it
Retry and pre-warm are the same goal approached from opposite ends — keep the summary from failing,
and make a failure self-correcting when it happens anyway. Tracking both here.
The measurement that motivates it (2026-08-14, this machine)
Same transcript throughout: the 2026-08-11 meeting, 500 segments / ~7.7k tokens / 32.6 minutes.
condition
time
Cold — model not loaded
36 s
Warm — model resident
13 s
The real failure, 2026-08-11
60.5 s → timed out
So a cold load costs ~23 s (36 − 13), and idle-cold is comfortably inside even the old 60 s
default. The failure was not explained by transcript size.
Why it failed anyway: the summary runs at the worst possible moment
Auto-summary fires immediately after the transcript is written — which is precisely when
transcription and diarization have just finished saturating the ANE/GPU and memory pressure is
highest. That session's log also shows CoreAudio reporting overload with Teams still running. Cold
load plus contention plus a busy machine pushed a 36 s job past 60 s.
Two consequences worth designing around:
Every post-meeting summary currently pays the cold-load penalty, because LM Studio unloads
the model between uses (observed again while measuring: no model loaded, hours after the last
summary). The penalty lands at the one moment the machine can least afford it.
Trigger the load when a recording STOPS, not when the summary request arrives. At that point the
user is done talking, the pipeline is starting its work, and there are typically seconds-to-minutes
before the transcript is ready — free wall-clock in which the model can load. By the time the
summary is requested it is resident, and the request is a 13 s job instead of a 36 s one.
Mechanism: LM Studio's REST API can load a model explicitly, and fetchLoadedState()
(/api/v0/models) already reports whether it is resident, so the check is cheap and exists.
Constraints:
Only if a summary is actually going to run — respect summary.enabled and the configured
provider. Never load a model for a user who has summaries off.
Never block the pipeline. Warming is best-effort and fire-and-forget; a failure to warm must
not delay or fail the transcript, which is the canonical artifact.
Don't fight the user's memory. If they unloaded the model deliberately to free VRAM,
re-loading it on every recording is hostile. Worth a setting, defaulting to on only when the
endpoint is local.
Consider deferring the summary slightly instead of (or as well as) warming — waiting for the
ASR/diarization pipeline to go quiet costs the user nothing, since nobody reads a summary in the
first seconds, and it removes the contention rather than merely out-waiting it.
How the two halves fit
Pre-warm removes the most common cause (cold load at peak contention).
Retry/heal covers everything pre-warming cannot: server not running at all, machine asleep,
model evicted under memory pressure, user quit LM Studio mid-pipeline.
Neither subsumes the other, and the retry classification work already done makes both safe: a
timeout or unreachable host is worth retrying, an auth failure or bad endpoint is not.
Related
#173 (timeout, fixed — a 600 s ceiling means slow no longer means lost). Note also that LM Studio
now REQUIRES a bearer token, so 401 is a live failure mode on this setup, not theoretical — which is
why the retry classifier must treat auth failures as non-retryable.
Problem
When the summary endpoint is unreachable or the model isn't loaded, the summary is lost permanently. The transcript survives (it is the canonical artifact and always written first), but the
-summary.mdnever appears, and nothing ever tries again — the user has to notice the failed notification and manually re-runParley summarize -i <transcript>.This is not hypothetical. Two real recordings lost their summary to endpoint failures:
-1001request timeouts against a local LM Studio that accepted the request and then generated for longer than the stock 60 sURLSessiontimeout (Summary request has no explicit timeout — 60s URLSession default kills long local-LLM summaries #173, since fixed with a configurable 600 s default).The realistic everyday cases are simpler still: LM Studio isn't running, the model was unloaded to free VRAM, or the machine was on battery/asleep when a recording finished. A meeting summary is exactly the thing a user assumes happened and only discovers is missing days later.
Why this fits the product
The summary is a derivative — the transcript is canonical — so a failure is recoverable in principle. Nothing currently acts on that. Given the airgapped, courtroom-grade framing, a silently-missing derivative is a smaller failure than a corrupt transcript but still a gap the system already has enough information to close on its own.
Sketch
Persist the intent, not just the failure. On a failed summary, record a pending marker (e.g.
~/Library/Application Support/Parley/pending-summaries.json, or a field in the session state) holding the transcript path, the failure kind, and an attempt count.Retry on the signals that actually mean "it might work now":
LMStudioSummaryProvider.fetchLoadedState()(/api/v0/models, 5 s timeout)Only retry what is worth retrying. The
URLErrormapping added alongside #173 makes the failure kinds distinguishable, which is what makes this safe:.timedOut,.cannotConnectToHost,.cannotFindHost,.notConnectedToInternet→ retrySummaryError.invalidEndpoint, auth failures, context-overflow after self-correction → do NOT retry; these need the user to change somethingConstraints that matter:
-summary.mdalready exists. A user who ransummarizeby hand must not get a duplicate or an overwrite.SummaryDisclosure, Make the airgap claim auditable: record whether a transcript's contents ever left the machine #138).Acceptance sketch
Related
#173 (timeout, fixed), #157 (summary quality), #37 (Apple Intelligence provider — a second provider makes the "don't silently switch providers" constraint more important, not less).
Part 2: prevent the failure, not only recover from it
Retry and pre-warm are the same goal approached from opposite ends — keep the summary from failing,
and make a failure self-correcting when it happens anyway. Tracking both here.
The measurement that motivates it (2026-08-14, this machine)
Same transcript throughout: the 2026-08-11 meeting, 500 segments / ~7.7k tokens / 32.6 minutes.
So a cold load costs ~23 s (36 − 13), and idle-cold is comfortably inside even the old 60 s
default. The failure was not explained by transcript size.
Why it failed anyway: the summary runs at the worst possible moment
Auto-summary fires immediately after the transcript is written — which is precisely when
transcription and diarization have just finished saturating the ANE/GPU and memory pressure is
highest. That session's log also shows CoreAudio reporting overload with Teams still running. Cold
load plus contention plus a busy machine pushed a 36 s job past 60 s.
Two consequences worth designing around:
the model between uses (observed again while measuring: no model loaded, hours after the last
summary). The penalty lands at the one moment the machine can least afford it.
fatal, but it does not stop the summary being slow and contended.
Pre-warm sketch
Trigger the load when a recording STOPS, not when the summary request arrives. At that point the
user is done talking, the pipeline is starting its work, and there are typically seconds-to-minutes
before the transcript is ready — free wall-clock in which the model can load. By the time the
summary is requested it is resident, and the request is a 13 s job instead of a 36 s one.
Mechanism: LM Studio's REST API can load a model explicitly, and
fetchLoadedState()(
/api/v0/models) already reports whether it is resident, so the check is cheap and exists.Constraints:
summary.enabledand the configuredprovider. Never load a model for a user who has summaries off.
not delay or fail the transcript, which is the canonical artifact.
re-loading it on every recording is hostile. Worth a setting, defaulting to on only when the
endpoint is local.
ASR/diarization pipeline to go quiet costs the user nothing, since nobody reads a summary in the
first seconds, and it removes the contention rather than merely out-waiting it.
How the two halves fit
model evicted under memory pressure, user quit LM Studio mid-pipeline.
Neither subsumes the other, and the retry classification work already done makes both safe: a
timeout or unreachable host is worth retrying, an auth failure or bad endpoint is not.
Related
#173 (timeout, fixed — a 600 s ceiling means slow no longer means lost). Note also that LM Studio
now REQUIRES a bearer token, so 401 is a live failure mode on this setup, not theoretical — which is
why the retry classifier must treat auth failures as non-retryable.