question about session management

86 views
Skip to first unread message

Beddhu Murali

unread,
Oct 16, 2025, 6:32:02 PM (10 days ago) Oct 16
to Chrome Built-in AI Early Preview Program Discussions
I see the following code at https://developer.chrome.com/docs/ai/prompt-api#clone_a_session

const controller = new AbortController(); stopButton.onclick = () => controller.abort(); const clonedSession = await session.clone({ signal: controller.signal, });

Assuming that the controller.signal was added with LanguageModel.create as in

const session = await LanguageModel.create({
... signal: controller.signal, });

My understanding is, if I click on the stop button, and the controller.abort runs,
it would destroy the session.

So, will the clone work after I click on the stop button?

It seems there are two behaviors for the use of signal. A signal used in prompt
will abort running the prompt, whereas a signal used in create will
destroy the session. Is that correct?

Thomas Steiner

unread,
Oct 16, 2025, 7:11:58 PM (10 days ago) Oct 16
to Beddhu Murali, Chrome Built-in AI Early Preview Program Discussions
Hi Beddhu,


Cheers,
Tom

Thomas Steiner, PhD—Developer Relations Engineer (blog.tomayac.comtoot.cafe/@tomayac)

Google Spain, S.L.U.
Torre Picasso, Pl. Pablo Ruiz Picasso, 1, Tetuán, 28020 Madrid, Spain

CIF: B63272603
Inscrita en el Registro Mercantil de Madrid, sección 8, Hoja M­-435397 Tomo 24227 Folio 25

----- BEGIN PGP SIGNATURE -----
Version: GnuPG v2.4.8 (GNU/Linux)

iFy0uwAntT0bE3xtRa5AfeCheCkthAtTh3reSabiGbl0ck
0fjumBl3DCharaCTersAttH3b0ttom.xKcd.cOm/1181.
----- END PGP SIGNATURE -----

On Fri, Oct 17, 2025, 00:32 Beddhu Murali <b...@eskns.com> wrote:
const controller = new AbortController(); stopButton.onclick = () => controller.abort(); const clonedSession = <span style="color-scheme: unset; forced-color-adjust: unset; mask-image: unset; mask-size: unset; mask-repeat: unset; mask-origin: unset; mask-clip: unset; mask-composite: unset; mask-mode: unset; math-depth: unset; position: unset; position-anchor: unset; text-size-adjust: unset; appearance: unset; color: unset; font-family: "Roboto Mono", monospace; font-feature-settings: unset; font-kerning: unset; font-language-override: unset; font-optical-sizing: unset; font-palette: unset; font-size: unset; font-size-adjust: unset; font-stretch: unset; font-style: unset; font-synthesis: unset; font-variant: unset; font-variation-settings: unset; font-weight: unset; position-area: unset; text-orientation: unset; text-rendering: unset; text-spacing-trim: unset; writing-mode: unset; zoom: unset; accent-color: unset; place-content: unset; place-items: unset; place-self: unset; alignment-baseline: unset; anchor-name: unset; anchor-scope: unset; animation-composition: unset; animation: unset; app-region: unset; aspect-ratio: unset; backdrop-filter: unset; backface-visibility: unset; background: unset; background-blend-mode: unset; baseline-shift: unset; baseline-source: unset; block-size: unset; border-block: unset; border: unset; border-radius: unset; border-collapse: unset; border-end-end-radius: unset; border-end-start-radius: unset; border-inline: unset; border-start-end-radius: unset; border-start-start-radius: unset; inset: unset; box-decoration-break: unset; box-shadow: unset; box-sizing: unset; break-after: unset; break-before: unset; break-inside: unset; buffered-rendering: unset; caption-side: unset; caret-animation: unset; caret-color: unset; clear: unset; clip: unset; clip-path: unset; clip-rule: unset; color-interpolation: unset; color-interpolation-filters: unset; color-rendering: unset; columns: unset; column-fill: unset; gap: unset; column-rule: unset; column-span: unset; contain: unset; contain-intrinsic-block-size: unset; contain-intrinsic-size: unset; contain-intrinsic-inline-size: unset; container: unset; content: unset; content-visibility: unset; corner-shape: unset; corner-block-end-shape: unset; corner-block-start-shape: unset; counter-increment: unset; counter-reset: unset; counter-set: unset; cursor: unset; cx: unset; cy: unset; d: unset; display: unset; dominant-baseline: unset; dynamic-range-limit: unset; empty-cells: unset; field-sizing: unset; fill: unset; fill-opacity: unset; fill-rule: unset; filter: unset; flex: unset; flex-flow: unset; float: unset; flood-color: unset; flood-opacity: unset; grid: unset; grid-area: unset; height: unset; hyphenate-character: unset; hyphenate-limit-chars: unset; hyphens: unset; image-orientation: unset; image-rendering: unset; initial-letter: unset; inline-size: unset; inset-block: unset; inset-inline: unset; interest-delay: unset; interpolate-size: unset; isolation: unset; letter-spacing: unset; lighting-color: unset; line-break: unset; line-height: unset; list-style: unset; margin-block: unset; margin: unset; margin-inline: unset; marker: unset; mask-type: unset; math-shift: unset; math-style: unset; max-block-size: unset; max-height: unset; max-inline-size: unset; max-width: unset; min-block-size: unset; min-height: unset; min-inline-size: unset; min-width: unset; mix-blend-mode: unset; object-fit: unset; object-position: unset; object-view-box: unset; offset: unset; opacity: unset; order: unset; orphans: unset; outline: unset; outline-offset: unset; overflow-anchor: unset; overflow-block: unset; overflow-clip-margin: unset; overflow-inline: unset; overflow-wrap: unset; overflow: unset; overlay: unset; overscroll-behavior-block: unset; overscroll-behavior-inline: unset; overscroll-behavior: unset; padding-block: unset; padding: unset; padding-inline: unset; page: unset; page-orientation: unset; paint-order: unset; perspective: unset; perspective-origin: unset; pointer-events: unset; position-try: unset; position-visibility: unset; print-color-adjust: unset; quotes: unset; r: unset; reading-flow: unset; reading-order: unset; resize: unset; rotate: unset; ruby-align: unset; ruby-position: unset; rx: unset; ry: unset; scale: unset; scroll-behavior: unset; scroll-initial-target: unset; scroll-margin-block: unset; scroll-margin: unset; scroll-margin-inline: unset; scroll-marker-group: unset; scroll-padding-block: unset; scroll-padding: unset; scroll-padding-inline: unset; scroll-snap-align: unset; scroll-snap-stop: unset; scroll-snap-type: unset; scroll-target-group: unset; scroll-timeline: unset; scrollbar-color: unset; scrollbar-gutter: unset; scrollbar-width: unset; shape-image-threshold: unset; shape-margin: unset; shape-outside: unset; shape-rendering: unset; size: unset; speak: unset; stop-color: unset; stop-opacity: unset; stroke: unset; stroke-dasharray: unset; stroke-dashoffset: unset; stroke-linecap: unset; stroke-linejoin: unset; stroke-miterlimit: unset; stroke-opacity: unset; stroke-width: unset; tab-size: unset; table-layout: unset; text-align: unset; text-align-last: unset; text-anchor: unset; text-autospace: unset; text-box: unset; text-combine-upright: unset; text-decoration: unset; text-decoration-skip-ink: unset; text-emphasis: unset; text-emphasis-position: unset; text-indent: unset; text-

Beddhu Murali

unread,
Oct 16, 2025, 8:05:02 PM (10 days ago) Oct 16
to Chrome Built-in AI Early Preview Program Discussions, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali
I have a follow up question.

If I clone a session that has a signal, what happens to the signal in the clone? Is there a way to specify the signal should not be cloned because I want to call abort on the original session after cloning.

Beddhu Murali

unread,
Oct 16, 2025, 8:34:00 PM (10 days ago) Oct 16
to Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
Please ignore the follow up question. I found the answer at the links you provided.

Beddhu Murali

unread,
Oct 16, 2025, 8:42:02 PM (10 days ago) Oct 16
to Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
Sorry. I misread the document. It says the clone operation can be aborted using an AbortSignal. My follow-up question earlier was about what happens to the signal that was supplied when the session was created using the create function. Will that be cloned as well?

Thomas Steiner

unread,
Oct 16, 2025, 11:12:36 PM (10 days ago) Oct 16
to Beddhu Murali, Chrome Built-in AI Early Preview Program Discussions, Thomas Steiner
Yes, the abort signal of the clone() operation is only to cancel the cloning. For the cloned session, you need a new abort signal instance to abort its operations independently from the original. 

Cheers,
Tom

Thomas Steiner, PhD—Developer Relations Engineer (blog.tomayac.comtoot.cafe/@tomayac)

Google Spain, S.L.U.
Torre Picasso, Pl. Pablo Ruiz Picasso, 1, Tetuán, 28020 Madrid, Spain

CIF: B63272603
Inscrita en el Registro Mercantil de Madrid, sección 8, Hoja M­-435397 Tomo 24227 Folio 25

----- BEGIN PGP SIGNATURE -----
Version: GnuPG v2.4.8 (GNU/Linux)

iFy0uwAntT0bE3xtRa5AfeCheCkthAtTh3reSabiGbl0ck
0fjumBl3DCharaCTersAttH3b0ttom.xKcd.cOm/1181.
----- END PGP SIGNATURE -----

Beddhu Murali

unread,
Oct 16, 2025, 11:29:24 PM (10 days ago) Oct 16
to Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
Thank you. I am not sure how to pass the new signal to the clone.

Thomas Steiner

unread,
Oct 16, 2025, 11:48:01 PM (10 days ago) Oct 16
to Beddhu Murali, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
const cloneCreationcontroller = new AbortController();
const clonedSession = await session.clone({ signal: cloneCreationcontroller.signal });

⬆️ This allows you to abort the cloning operation itself. You rarely will need this because cloning is fast. 




const clonePromptController = new AbortController();
stopButton.onclick = () => clonePromptController.abort();
const result = await clonedSession.prompt("Write me a poem", { signal: clonePromptController.signal });

⬆️ This allows you to abort the prompting operation on the cloned session. You will typically need this to allow the user to cancel a prompt if it's not helpful.

--

Beddhu Murali

unread,
Oct 17, 2025, 11:49:23 AM (9 days ago) Oct 17
to Chrome Built-in AI Early Preview Program Discussions, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali
Sorry, that didn't answer my question. Based on your answer, I am suspecting you might be an AI bot.

Anyway, let me ask my question in a different way. Consider the following code:

const controller = new AbortController();

const session = await LanguageModel.create({ signal: controller.signal, });

const clonedSession = await session.clone();

controller.abort()

In the above code, what will the call to controller.abort() do? Will it destroy both session and clonedSession or only session? It depends on how the method clone is implemented.

Thomas Steiner

unread,
Oct 17, 2025, 3:12:30 PM (9 days ago) Oct 17
to Beddhu Murali, Chrome Built-in AI Early Preview Program Discussions, Thomas Steiner
On Fri, Oct 17, 2025, 08:49 Beddhu Murali <b...@eskns.com> wrote:
Sorry, that didn't answer my question. Based on your answer, I am suspecting you might be an AI bot.

With all due respect, I'm disengaging from this conversation. 👋 

Beddhu Murali

unread,
Oct 18, 2025, 1:27:19 PM (8 days ago) Oct 18
to Chrome Built-in AI Early Preview Program Discussions, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali
My apologies. Didn't mean to offend you. Hope you will respond to the technical question.

Nikita Malyschkin

unread,
Oct 18, 2025, 3:31:33 PM (8 days ago) Oct 18
to Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
Since even the AI bots already signed off let me help you out:
1. Have you tried running the above code snippets and see what will happen?
2. What happens when you run it and what would you expect to happen?

All the best
Nikita

PS: Always be nice to AI, say please and thank you. The singularity won't be happy to see how you've treated its ancestors 😄

Beddhu Murali

unread,
Oct 18, 2025, 8:12:13 PM (8 days ago) Oct 18
to Chrome Built-in AI Early Preview Program Discussions, Nikita Malyschkin, Beddhu Murali, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
Thank you! I tried something simpler, just now.

In the following screenshot, 

1. I get a LanguageModel instance after passing an AbortController.signal to it.
2. I prompt the model.
3. I call abort on the controller before the call to prompt resolves.
4. The model continues and produces an output.
5. I prompt the model again.
6. It produces an output again.

My understanding is calling abort on the controller should have the same effect as calling destroy on the model instance. But, I am not seeing that behavior. I have tested destroy earlier and it works as expected.

Screenshot 2025-10-18 185443.png

I hear you about the singularity!

Nikita Malyschkin

unread,
Oct 19, 2025, 4:37:36 AM (7 days ago) Oct 19
to Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali, Nikita Malyschkin, Thomas Steiner, Chrome Built-in AI Early Preview Program Discussions
I see the misunderstanding here.
So the abort controller aborts the operation that it gets appended to, nothing more.
In your example above the creation operation has already finished, so the abort signal will be ignored.
If you want to be able to abort a prompt execution you would need to do something like this:
Screenshot 2025-10-19 at 10.17.14.png
But again: this will only abort the prompt, not destroy the session.

@Thomas
I think the misunderstanding is coming from the docs here:
https://github.com/webmachinelearning/prompt-api?tab=readme-ov-file#session-destructionScreenshot 2025-10-19 at 10.28.40.png 
I think that the "Otherwise" section refers to calling the destroy function on the session, while the section above refers to signalling abort (since you can't call destroy before the session is created).

Hope this helps 🙂

Thomas Steiner

unread,
Oct 20, 2025, 12:39:00 PM (6 days ago) Oct 20
to Nikita Malyschkin, Chrome Built-in AI Early Preview Program Discussions, Beddhu Murali, Thomas Steiner
Nikita, thanks for jumping in and clarifying the behavior regarding the abort signal on session creation versus prompt execution.

Beddhu, apologies accepted, but please be very careful in the future with calling someone an AI bot.

Let me help you with a real-world movie theater analogy: 

–––––
const session = await LanguageModel.create({signal}); 
The film operator turns the projector on, gets it warmed up, and puts the film roll in, then they leave. This signal stops the preparation steps of the film operator.
–––––


–––––
const response = await session.prompt(prompt, {signal});
The low-paid intern starts the projection. This signal stops the playing of the movie by nudging the intern.
–––––

Hope this makes the difference clearer. Both are different processes that can be stopped independently, but telling the film operator to stop when the movie is already playing doesn't do anything, because they have left the movie theater already and are having a drink in a pub nearby. 

Cheers,
Tom
🍿 

--
Reply all
Reply to author
Forward
0 new messages