Skip to content

Summary request has no explicit timeout — 60s URLSession default kills long local-LLM summaries #173

Description

@fmasi

What happened

A 24-minute meeting (2026-08-04) produced a transcript but no summary. The app showed a "Summary Failed" notification. It was misread as a permission problem — it is not; no TCC path is involved.

Evidence

Unified log, app pid 1562, endpoint http://127.0.0.1:1234 (LM Studio):

15:56:33.451  [C16 IPv4:1234 ... interface: lo0] event: flow:finish_connect @0.001s
15:56:33.451  nw_connection_report_state_with_handler_on_nw_queue [C16] reporting state ready
15:57:34.450  Task <CA6F022B...>.<4> summary for task failure
              {transaction_duration_ms=60872, response_status=200, response_bytes=0, ...}
15:57:34.450  Task <CA6F022B...>.<4> finished with error [-1001]
              Error Domain=NSURLErrorDomain Code=-1001
15:57:34.450  [eu.fmasi.parley:transcription] Summary generation failed: <private>
  • -1001 = NSURLErrorTimedOut.
  • The connection succeeded (flow:finish_connect, state ready, response_status=200) — LM Studio accepted the request and then produced no bytes within the window (response_bytes=0) while generating.
  • transaction_duration_ms=60872 — the stock URLSession 60 s request timeout.

Root cause

Neither summary provider sets timeoutInterval on the chat request, so both inherit the 60 s default. The only explicit timeouts in the codebase are on short probes:

  • TranscriberCore/LMStudioSummaryProvider.swift:268request.timeoutInterval = 5 (the /api/v0/models load-state probe)
  • TranscriberCore/ModelManifestService.swift:14110

60 s is simply the wrong order of magnitude for a local LLM summarising a long transcript: a cold model load plus generation over a 24-minute meeting routinely exceeds it. Reproduced by hand on the same transcript with the model already warm: 24.8 s — i.e. we are close enough to the ceiling that a cold start reliably crosses it.

Suggested fix

  • Set an explicit, generous timeoutInterval on the chat request in both OpenAISummaryProvider and LMStudioSummaryProvider (a local model has no reason to be held to a network default). Consider timeoutIntervalForResource separately from timeoutIntervalForRequest, since the concern is total generation time, not stalled bytes.
  • Make it configurable in SummaryConfig for slow models / large contexts.
  • Improve the failure notification: -1001 should read as "the model took longer than Ns to respond" rather than a bare localizedDescription, which is what made this look like a permission error.

Notes

Not a regression from any recent change — the default has always applied. Surfaced now because summaries are auto-run after every recording (#134).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions