diff --git a/docs/website/content/docs/reference/api/index.mdx b/docs/website/content/docs/reference/api/index.mdx index 3c35d1d847..6e7b9f29e5 100644 --- a/docs/website/content/docs/reference/api/index.mdx +++ b/docs/website/content/docs/reference/api/index.mdx @@ -1294,9 +1294,10 @@ console.log(await response.text); Unloads a previously loaded model from the server. -When the last model is unloaded (no more models remain), this function -automatically closes the RPC connection, allowing the process to exit -naturally without requiring manual cleanup. +When no models or providers remain active, the SDK can auto-close the RPC +connection so the host process exits naturally. The default flips by +runtime: **on** for Node/Electron, **off** for Bare. Pass `autoClose` to +override. **Signature**: @@ -1308,6 +1309,18 @@ function unloadModel(params: UnloadModelParams): Promise; - `QvacErrorBase` — When the response type is invalid or when the unload operation fails +**Example**: + +```ts +await unloadModel({ modelId }); + +// Force close on Bare +await unloadModel({ modelId, autoClose: true }); + +// Keep the connection open on Node/Electron +await unloadModel({ modelId, autoClose: false }); +``` + --- ## Objects diff --git a/packages/sdk/client/api/unload-model.ts b/packages/sdk/client/api/unload-model.ts index 26f3e26cf3..a01d699a29 100644 --- a/packages/sdk/client/api/unload-model.ts +++ b/packages/sdk/client/api/unload-model.ts @@ -1,3 +1,4 @@ +import { isBare } from "which-runtime"; import { type UnloadModelRequest, type UnloadModelParams } from "@/schemas"; import { send, close } from "@/client/rpc/rpc-client"; import { stopLoggingStreamForModel } from "@/client/logging-stream-registry"; @@ -13,12 +14,15 @@ const logger = getClientLogger(); * Unloads a previously loaded model from the server. * * When the last model is unloaded (no more models remain), this function - * automatically closes the RPC connection, allowing the process to exit - * naturally without requiring manual cleanup. + * automatically closes the RPC connection on Node/Electron, allowing the + * process to exit naturally without requiring manual cleanup. On Bare the + * connection is left open by default so long-lived workers survive a routine + * unload; pass `autoClose: true` to opt in to closing. * * @param params - The parameters for unloading the model * @param params.modelId - The unique identifier of the model to unload * @param params.clearStorage - Whether to clear the storage for the model + * @param params.autoClose - Override the runtime-default auto-close behavior * @throws {QvacErrorBase} When the response type is invalid or when the unload operation fails */ export async function unloadModel(params: UnloadModelParams) { @@ -39,8 +43,9 @@ export async function unloadModel(params: UnloadModelParams) { stopLoggingStreamForModel(params.modelId); - // Auto-close when no models remain AND no providers are active + const shouldAutoClose = params.autoClose ?? !isBare; if ( + shouldAutoClose && response.hasActiveModels === false && response.hasActiveProviders === false ) { diff --git a/packages/sdk/schemas/unload-model.ts b/packages/sdk/schemas/unload-model.ts index d0d518d88d..cf977fb038 100644 --- a/packages/sdk/schemas/unload-model.ts +++ b/packages/sdk/schemas/unload-model.ts @@ -3,10 +3,13 @@ import { z } from "zod"; export const unloadModelParamsSchema = z.object({ modelId: z.string(), clearStorage: z.boolean().default(false), + autoClose: z.boolean().optional(), }); -export const unloadModelRequestSchema = unloadModelParamsSchema.extend({ +export const unloadModelRequestSchema = z.object({ type: z.literal("unloadModel"), + modelId: z.string(), + clearStorage: z.boolean().default(false), }); export const unloadModelResponseSchema = z.object({