Skip to content

notebooklm: send audio custom instructions as UniversalAudioDetails.prompt - #40

Open
faughnn wants to merge 1 commit into
tmc:mainfrom
faughnn:feat/audio-overview-prompt-steer
Open

notebooklm: send audio custom instructions as UniversalAudioDetails.prompt#40
faughnn wants to merge 1 commit into
tmc:mainfrom
faughnn:feat/audio-overview-prompt-steer

Conversation

@faughnn

@faughnn faughnn commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Custom instructions for an Audio Overview are currently unusable. Any non-empty
instruction string fails:

nlm audio create <notebook> "Educational walkthrough; spell out acronyms."
→ InvalidInput (API error 3 on R7cb6c)

The same notebook succeeds immediately with "", so it is not an auth, source
or notebook problem.

Cause

CreateAudioOverviewWithOptions gates the CreateUniversalArtifact path on
opts.Instructions == "":

if opts.Instructions == "" && opts.AudioType == DEEP_DIVE &&
   opts.Length == DEFAULT && opts.Language == "en" {
        → CreateUniversalArtifact          // accepted by the server
}
// otherwise
req := &pb.CreateAudioOverviewRequest{ CustomInstructions: opts.Instructions, ... }
        → CreateAudioOverview              // legacy; server rejects

So supplying instructions actively diverts the request away from the shape the
server accepts and into the legacy one it no longer does. Meanwhile
UniversalAudioDetails already carries a prompt field (field 1) intended for
exactly this, and nothing populates it.

Fix

Populate prompt from opts.Instructions and drop the emptiness condition from
the gate, so instructions ride the modern request rather than diverting to the
legacy one. Behaviour with empty instructions is unchanged.

Verification

Against the live API, not just unit tests:

  • Before: any non-empty instruction returned InvalidInput.
  • After: the request is accepted, and the instruction is honoured. An overview
    told to open with a specific marker phrase began with exactly that phrase.

One caveat worth recording for anyone testing this: a sweeping style instruction
("speak entirely in limericks") was accepted but not followed, so the model
appears to decline wholesale format overrides. Targeted instructions about
content, emphasis and delivery do take effect. Absence of an error is therefore
not proof the steer applied — check the output.

Test

Adds TestUniversalAudioDetailsPromptRoundTrip, pinning prompt at wire index
0. A regression there would silently drop the steer and generate default audio
with no error surfaced, which is the failure mode this change exists to remove.

go test ./notebooklm/... ./cmd/... passes; no existing test asserted the old
gating.

…rompt

Custom instructions for an Audio Overview were unusable: any non-empty
instruction string failed with InvalidInput (API error 3 on R7cb6c).

CreateAudioOverviewWithOptions gated the CreateUniversalArtifact path on
opts.Instructions == "", so supplying instructions diverted the request to
the legacy CreateAudioOverviewRequest.custom_instructions field, which the
server no longer accepts. UniversalAudioDetails already carries a prompt
field (field 1) for exactly this, but it was never populated.

Populate prompt from opts.Instructions and drop the emptiness condition, so
instructions travel on the modern request instead of diverting to the legacy
one. Adds a round-trip test pinning prompt at wire index 0, since a silent
regression there drops the steer without surfacing an error.

Verified against the live API: instructions are accepted and honoured. A
generated overview instructed to open with a specific marker phrase began
with exactly that phrase, where the same request previously errored.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant