Your agent cannot sit through an hour of recorded meeting
An hour of audio is not something a tool call can wait for. It gets queued, and you get a handle back immediately.
Someone recorded the meeting and wants the decisions out of it. The file is fifty-six minutes long, and every part of the obvious approach breaks.
The model cannot listen to it: audio is not something most clients can put in front of a model, and the ones that can charge for the whole duration whether or not anything was said. A transcription API can, but an hour takes longer than any tool call is allowed to run, so the call times out and your agent retries, and now the same hour is being paid for twice.
And when the text finally arrives it is one undivided block, which answers no question anyone actually has. Nobody wants the transcript. They want what was decided and who committed to it.
Running a speech model on your own machine is possible and it is slow: real time or worse on a laptop, so an hour of audio costs an hour of your machine. That would be tolerable if it ran in the background, but a tool call is not a background job. It has to answer.
Speaker separation is the part that quietly does not work. Splitting a recording into who spoke when is a separate model from the one that turns sound into words, and running it well is not a matter of installing a package. Without it a four-person meeting comes back as one continuous voice, and every attribution your agent makes afterwards is a guess.
There is also the arithmetic nobody does up front: an hour of transcript is roughly forty thousand tokens. Returning it into a conversation does not just cost that once. It sits in the context and degrades every answer that comes after it, including the ones about something else entirely.
Audio longer than a few minutes is queued. listen returns immediately with a handle and status: running, and the same handle serves the result once it is ready.
upload(filename="meeting.m4a", content_type="audio/mp4")
-> key, upload_url
curl -T meeting.m4a "<upload_url>"
listen(key="<key>")
-> handle, status: running, estimated_minutes
result(handle="<handle>", outline=true)
-> who spoke, and when
result(handle="<handle>", find="deadline")
-> excerpts, each with its timestamp
result(handle="<handle>", time="9:30-11:00")
-> that stretch, as turns of speechlisten in balanced mode costs 0.005 EUR per minute of audio, so a fifty-six minute meeting is about 0.28 EUR. exact costs 0.008 EUR per minute and uses the strongest model: worth it on poor recordings, crosstalk and heavy accents.
Both modes separate speakers. That is not an upsell tier, it is part of what the mode guarantees, and an engine that cannot do it does not get used for this work.
Duration is measured from the file, not estimated from its size, and a declared duration that disagrees with the file's weight is not trusted. You are charged once, on the real duration, whether or not you ever collect the result.
Querying the transcript afterwards is free, however many times you do it: the work was paid for when it ran.
- Four hours is the ceiling on a single recording. Longer than that, split the file.
- A queued job can be cancelled while it is still waiting and the credit comes back. Once an engine has started, it cannot: the money has already left.
- Speaker labels are
Speaker A,Speaker Band so on. Nothing identifies who those people are, and no voice is matched against any stored identity.
Without markup
This page in markdown: /problems/transcribe-an-hour-long-meeting.md. All 20 of them in one file: /llms-full.txt.