NAME

Langertha::Engine::LMStudio - LM Studio native REST API

VERSION

version 0.503

SYNOPSIS

use Langertha::Engine::LMStudio;

my $lmstudio = Langertha::Engine::LMStudio->new(
    url   => 'http://localhost:1234',
    model => 'qwen2.5-7b-instruct',
);

print $lmstudio->simple_chat('Hello from LM Studio native API');

$lmstudio->simple_chat_stream(sub {
    print shift->content;
}, 'Explain Perl Moo vs Moose');

DESCRIPTION

Provides access to LM Studio's native local REST API (/api/v1/...), without using the OpenAI-compatible /v1 endpoints.

Implemented operations:

The native chat endpoint takes no client tools: passing a non-empty tools list croaks, use the "openai" or "anthropic" wrapper for tool calling. A tool_choice is never sent (a forced one warns).

The native input is one user turn: a plain string, or an array of { type => 'text', content } and { type => 'image', data_url } parts (Langertha::Content::Image goes as a base64 data URL). The endpoint takes no assistant messages, so a history that contains assistant turns is cut to the user turn(s) after the last one, with a warning; system messages still go out as system_prompt. For client-side history use the "openai" or "anthropic" wrapper.

Multi-turn on this wire is server-side state instead: LM Studio stores each chat (store defaults to true on the server) and answers with a response_id ("id" in Langertha::Response). Pass it back as previous_response_id together with the next user turn only; both previous_response_id and store are passed through unchanged:

my $first = await $lmstudio->chat_f( messages => [ 'My name is Ada.' ] );
my $next  = await $lmstudio->chat_f(
    messages             => [ 'What is my name?' ],
    previous_response_id => $first->id,
);

# a throwaway call that leaves no stored chat behind
await $lmstudio->chat_f( messages => [ 'Hi' ], store => JSON::MaybeXS::false );

Langertha does not send store by default, so every call is stored by the server. With store false the server returns no response_id, and the final streamed chunk then carries no finish_reason.

Authentication is optional. If api_key (or LANGERTHA_LMSTUDIO_API_KEY) is set, requests include Authorization: Bearer ....

THIS API IS WORK IN PROGRESS

api_key

Optional LM Studio API token for bearer authentication. If not provided, reads from LANGERTHA_LMSTUDIO_API_KEY. When undefined, no bearer header is sent.

openapi_file

Returns the bundled native LM Studio OpenAPI spec file share/lmstudio.yaml.

openai

my $oai = $lmstudio->openai;
my $oai = $lmstudio->openai(model => 'other-model');

Returns a Langertha::Engine::LMStudioOpenAI instance configured for LM Studio's OpenAI-compatible /v1 endpoint. Carries over model, api_key, system_prompt, and temperature by default, and "connect_address" in Langertha::Role::HTTP while the url stays on its host.

anthropic

my $anthropic = $lmstudio->anthropic;
my $anthropic = $lmstudio->anthropic(model => 'other-model');

Returns a Langertha::Engine::LMStudioAnthropic instance configured for LM Studio's Anthropic-compatible /v1/messages endpoint. Carries over model, api_key, system_prompt, and temperature by default, and "connect_address" in Langertha::Role::HTTP while the url stays on its host.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.