LM Studio JS SDK

repository·main·Indexed 23 days ago

https://github.com/lmstudio-ai/lmstudio-js

The official TypeScript/JavaScript SDK for LM Studio, providing developers with tools to interact with local LLMs. It enables advanced control over model lifecycle, hardware configuration (such as GPU offload and context length), and agentic workflows. Key features include chat and completion management via the Chat and ChatMessage classes, embedding generation, and the ability to load, configure, and unload models from memory. It is designed for both Node.js and browser environments.

Tokens
25.3K
Snippets
25
Records
157
Agent score
83%

What's inside lmstudio-js

  1. Capabilities of lmstudio-js

    main

    The lmstudio-js SDK provides several features for working with local LLMs:

    • Chat and Completions: Use LLMs to respond in chats or predict text completions.
    • Agentic Workflows: Define functions as tools to turn LLMs into autonomous agents that run locally.
    • Model Management: Load, configure, and unload models from memory.
    • Embeddings: Generate embeddings for text.
    • Environment Support: Works in both browser and any Node-compatible environments.
  2. Comparison: lmstudio-js vs OpenAI SDK

    main

    While the openai SDK is designed for proprietary models, lmstudio-js is built specifically for local LLM workflows. Key advantages of lmstudio-js include:

    • Memory Management: Ability to manage loading and unloading models from memory.
    • Hardware Configuration: Configuring load parameters such as context length and GPU offload settings.
    • Advanced Features: Support for speculative decoding.
    • Model Metadata: Accessing information about a model, such as its context length and size.
    • Developer Experience: Designed from the ground up for TypeScript/JavaScript developers rather than being an automatically generated client.
  3. Quick start with LMStudioClient

    main

    You can use LMStudioClient to load a model and generate a response. This example demonstrates initializing the client, selecting a specific model, and calling the respond method to get a text completion.

    import { LMStudioClient } from "@lmstudio/sdk";
    const client = new LMStudioClient();
    
    const model = await client.llm.model("llama-3.2-1b-instruct");
    const result = await model.respond("What is the meaning of life?");
    
    console.info(result.content);
  4. Configure Artifact Dependencies

    main

    Artifacts can depend on either concrete models or other artifacts. Dependencies are categorized by a purpose: baseModel, draftModel, or custom.

    Model Dependencies (type: "model")

    Used when an artifact requires a specific model to function.

    • modelKeys: An array of strings used to identify matching models. Any model matching any key in this list satisfies the dependency.
    • sources: An array of ModelDownloadSource objects describing how to acquire the model (e.g., via a URL).

    Artifact Dependencies (type: "artifact")

    Used when an artifact depends on another artifact.

    • owner: The owner of the dependency artifact.
    • name: The name of the dependency artifact.
    export type ArtifactDependency = ArtifactModelDependency | ArtifactArtifactDependency;
    
    export interface ArtifactModelDependency extends ArtifactDependencyBase {
      type: "model";
      modelKeys: Array<string>;
      sources: Array<ModelDownloadSource>;
    }
    
    export interface ArtifactArtifactDependency extends ArtifactDependencyBase {
      type: "artifact";
      owner: string;
      name: string;
    }
  5. Create interactive UI elements with VirtualModelCustomFieldDefinition

    main

    Custom fields allow you to add interactive controls to the LM Studio UI for a specific virtual model. These fields can trigger 'effects' that modify the model's behavior (like setting Jinja variables or prepending/appending to the system prompt).

    Supported field types:

    • boolean: A toggle field. Supports effects: setJinjaVariable, prependSystemPrompt, and appendSystemPrompt.
    • string: A text input field. Supports effect: setJinjaVariable.
    • select: A dropdown menu. Requires an options array of { label: string, value: string }. Supports effect: setJinjaVariable.
    • number: A numeric input. Can include a slider configuration with min, max, and step. Supports effect: setJinjaVariable.

    All custom fields require a key, displayName, description, and defaultValue.

  6. How Chat and ChatMessage handle files

    main

    Both Chat and ChatMessage provide mechanisms to manage files (like images) attached to messages. Files are represented by FileHandle objects.

    • Retrieval:
      • Chat.getAllFiles(client): Returns all files in the entire history.
      • Chat.files(client): An async generator to iterate over all files in the history.
      • ChatMessage.getFiles(client): Returns files attached to a specific message.
    • Consumption: You can use .consumeFiles(client, predicate) or .consumeFilesAsync(client, predicate) to find and remove specific files from the history/message based on a condition. This is useful for pre-processors that transform files and need to remove the originals.
  7. How download planners work for artifacts and models

    main

    LM Studio provides ArtifactDownloadPlanner instances to manage complex download requirements. Instead of a simple download, a planner allows you to monitor progress, handle dependencies, and resolve specific versions or quantization types.

    Artifact Download Planner

    Use createArtifactDownloadPlanner to manage the download of a specific artifact (e.g., a plugin or tool) belonging to an owner and name.

    Model Download Planner

    Use createModelDownloadPlanner to manage model downloads from a specific source (e.g., Hugging Face).

    Resolution Preferences

    You can provide resolutionPreference to guide the planner toward specific files or quantization names:

    • fileName: Resolve by a specific filename.
    • quantName: Resolve by a specific quantization name.

    Important: Download planners should be used with the using keyword (if using TypeScript's explicit resource management) or manually disposed of to prevent memory leaks, as they register with a FinalizationRegistry to warn about un-disposed planners.