Changelog
Source:NEWS.md
rlmstudio (development version)
-
Three changes for a model name that LM Studio cannot serve:
-
lms_embed()now checks which model answered, aslms_chat_openai()andlms_chat_openresponses()do. In LM Studio 0.4.26+4, one embedding model was loaded./v1/embeddingsthen answered an unknown name with vectors from that embedding model.lms_embed()returned those vectors. The new check reads themodelfield of each reply. If that field differs from the asked name and no loaded instance of that model has that id, the call now aborts withrlmstudio_model_mismatch. After a request that succeeded, the condition carries aresultsfield. The check can send a model-list request. If that request fails, the inputs of that embeddings request fail. A lost server or a status of 401, 403, or 404 ends the call. -
lms_chat_batch()andlms_embed()now stop at the first status 400 whose error text starts with “No models loaded”. In LM Studio 0.4.26+4 with no model loaded,/v1/chat/completions,/v1/responses, and/v1/embeddingsgave this error for an unknown name. Before, the batch sent every input, and each one failed. The condition carries aresultsfield, as at the other stops. Forlms_embed(), that field is there only after a request that succeeded. Anrlmstudio_api_errornow carries aserver_messagefield, the error text that the server sent, orNULL. -
lms_chat_batch()andlms_embed()now keep each reply id that a model-list lookup accepted, for the rest of the call. A later reply with a kept id sends no lookup. Before,lms_chat_batch()against a model loaded under another id sent one model-list request for each input.
-
list_instances()has a new fifth column,remaining_ttl_seconds, so each load configuration column moves one position to the right. This double column holds theremaining_ttl_secondsthat the model list gives for each instance. If the field is absent ornull, the column holdsNA. In LM Studio 0.4.26+4, an instance loaded with no ttl has no such field, so it holdsNA. Iflist_instances()finds no instance, the zero-row frame also has this column. A load configuration field namedremaining_ttl_secondsnow gives the columnconfig.remaining_ttl_seconds. The check covers loaded instances of a model whose type is intype. If such aremaining_ttl_secondsis not a number ornull, the call aborts withrlmstudio_bad_response.A request to a
hostwhose hostname islocalhost, in any letter case,127.0.0.1, or::1no longer goes through a proxy. The proxy environment variables, such ashttp_proxyorall_proxy, set that proxy. Before, unlessno_proxylisted the host, curl sent the request and its text to the proxy. The call then failed, or got its answer from the proxy and not straight from the server. A request that starts at any other host follows the proxy variables as before.vignette("getting-started")now tells you to open the LM Studio app once after the install. The vignette starts the server withport = 1234, because LM Studio otherwise uses the port that it used last time. It shows how to find a model key in the LM Studio model catalog. It also names thestatusof a finished download,"completed".lms_server_start()with noportnow says that the server started “on the port that LM Studio used last”, not “on the default port”. The README, the other vignettes, and the help examples, apart from one that shows another port, now start the server withport = 1234. The other functions that send requests ask that port by default, and theporthelp now says so.install_lmstudio(method = "browser")now tells you to open the LM Studio app once before you restart R.With
options(rlmstudio.quiet = TRUE),check_lms_version(),install_lmstudio(method = "browser"), and the print of a chat result now show no alerts. Before,check_lms_version()showed an alert for a missing CLI, for version output that did not parse, and for a version that was too old.install_lmstudio()showed its request to install the software, and the print showed that log probability data was empty or missing. The function results do not change.-
Two cases that cannot return what you asked for now give a warning with its own class. The
rlmstudio.quietoption does not hide either warning.-
lms_load(echo_load_config = TRUE)on a model that is already loaded, withforce = FALSE, returns the model key, and now warns with the classrlmstudio_no_load_config. Before, it showed an alert with no class. -
lms_chat_openai(logprobs = TRUE)andlms_chat(api_type = "openai", logprobs = TRUE)return a result whoselogprobsisNULL, and now warn with the classrlmstudio_no_logprobs. Ifsimplify = TRUEand the batch reads at least one reply,lms_chat_batch(api_type = "openai", logprobs = TRUE)gives one such warning for the whole batch. Ifsimplify = TRUEandformat = "vector", alogprobs = TRUEbatch on that route that does not abort returns the list, as before. Its warning now says that the vector format “cannot store the<lms_chat_result>replies of the"openai"route”. Before, it said that the vector format “cannot store logprobs dataframes”.
-
When no server answers, the
rlmstudio_no_servererror now says how to start the server. The hostnamelocalhostcan be in any letter case. If the hostname ofhostislocalhostor127.0.0.1, the error says to runlms_server_start()with the port ofhost. Ifhostnames no port, that port is 1234. For any otherhost, the error names that host and says to start the server there. The headlessinstall_lmstudio()message now nameslms_server_start(port = 1234), and the “Server not running” help section gives the same hint.
rlmstudio 0.3.0
CRAN release: 2026-10-02
Breaking changes
-
Each
TRUE/FALSEargument now aborts on any other value, with a message that names the argument. Before,NA,"yes",1, andNULLacted asFALSE. This coverssimplify,logprobs,force,echo_load_config,cors,loaded,detailed,json, andverbose.-
flash_attentionandoffload_kv_cache_to_gpuoflms_load()takeTRUE,FALSE, orNULL. Before, the function sent the result ofas.logical()for any value.
-
quietoflist_models()andlms_chat_batch()now defaults toNULL, which follows therlmstudio.quietoption.TRUEorFALSEoverrides the option.If a character
inputholds more than one string,lms_chat(),lms_chat_native(), andlms_chat_openresponses()now abort. Uselms_chat_batch()to send several prompts.-
lms_chat_batch()no longer stops at a failed input. It stores the failure, goes on to the next input, and warns once at the end with the positions of the failed inputs. In a list result, the element of a failed input holds the condition. Where the result is text, it holdsNA.- The batch still aborts on a lost server, on status 401, 403, or 404, and on a model that the server cannot find. The condition carries the replies so far in a
resultsfield. - With
api_type = "native", the batch ignoreslogprobs = TRUEand warns once.
- The batch still aborts on a lost server, on status 401, 403, or 404, and on a model that the server cannot find. The condition carries the replies so far in a
If no server answers,
list_models(),lms_download(), andlms_download_status()now abort withrlmstudio_no_server. Before, they returned an empty data frame orNULL.lms_download()returns the job id string, or"already_downloaded"invisibly. A reply with no job id now aborts withrlmstudio_bad_response. Before, the call returnedTRUE.lms_server_start()now waits up to 10 seconds for the REST API to answer before it returns. Setwait = 0to return as soon as the CLI does, as before.lms_server_stop()with no server running now prints a message and returns. Before, it aborted.The logprobs data frame has a new last column,
step, that numbers the steps of the reply.lms_score_expected()now scores the first step alone. It also adds up candidates that give the same label, such as"3"and" 3".With
simplify = TRUE, a reply fromlms_chat_native()andlms_chat_openresponses()now carries aresponse_idattribute. Soidentical()of such a reply and a plain string returnsFALSE.
New features
New
lms_embed()turns texts into embedding vectors. It returns a numeric matrix with one row per text. It sends the texts in batches ofbatch_size(default 100) and shows a progress bar for more than one batch.New
list_instances()returns one row per loaded model instance, with a column for each field of its load configuration.New
lms_server_ready()tells whether a host answers as an LM Studio server that you can use. It returnsTRUEorFALSE, and it never aborts on a failed request.The package can now use an LM Studio server that requires an API token. Each function that reaches the REST API takes a
tokenargument. Without it, the package reads therlmstudio.tokenoption, then theRLMSTUDIO_API_TOKENenvironment variable. See?rlmstudio_token.Structured output:
lms_chat_openai()andlms_chat(api_type = "openai")take aschemaargument, a JSON Schema written as a named list. Withsimplify = TRUE, the reply comes back parsed into an R value. Withformat = "data.frame"andlogprobs = FALSE,lms_chat_batch()adds one column per top-level property of an object schema.Chat threads:
lms_chat(),lms_chat_native(), andlms_chat_openresponses()takeprevious_response_idto continue a stored thread. Pass the earlier reply itself, or itsresponse_idattribute. A newstoreargument turns off the storage of a reply on the server.lms_chat(),lms_chat_openai(), andlms_embed()take attlargument. It sets the seconds that a model loaded by the request stays loaded with no request.lms_chat()takes it on the"openai"route only.lms_server_start()gainswait,host, andtokenarguments for its readiness check. It also checksportandcorsbefore the CLI runs.With
format = "data.frame",lms_chat_batch()adds the reply id and token counts as columns. On the native route, it also adds the speed and timing columns from the replystats.If
context_lengthis larger than the maximum that the model list gives for the model,lms_load()warns with classrlmstudio_context_above_max.New condition classes let you catch each kind of failure with
tryCatch(). They arerlmstudio_no_server,rlmstudio_api_error,rlmstudio_bad_response, andrlmstudio_model_mismatch. Anrlmstudio_api_errorcarries the HTTPstatusand the errorcodeof the reply. See?rlmstudio-conditions.Two new vignettes.
vignette("chat-options")shows how to control a chat from an R script.vignette("text-analysis")shows how to analyze a data frame of texts. Thegetting-startedandheadless-configvignettes are rewritten.The vignettes now ship with output knitted ahead of time from a live LM Studio. A build or check of the package runs no vignette code.
Bug fixes and new checks
Each argument that names a model, a job, a thread, or a model type is now checked before the request. A bad value aborts with a message that names the argument. Text arguments that hold
NAabort too.lms_chat_openai()now checksmessagesbefore the request. It aborts on a value that the server cannot read, with a message that names the fault.A
streamin...of a chat function now aborts unless it isFALSEorNULL. The package reads a whole reply only.Each function now checks the shape of a reply before it reads it. A reply that the package cannot read aborts with
rlmstudio_bad_response. Before, many such replies gave a base R error, or returnedNULLor a wrong value.A reply body is now read as JSON text alone, whatever its
Content-Typeheader says. Before, a body whose text was a URL or a file path made the package read that URL or file.lms_chat_native()andlms_chat_openresponses()now return the answer of a reasoning model. Before, they returned its reasoning.If a model other than the one asked for answers,
lms_chat_openai()andlms_chat_openresponses()abort withrlmstudio_model_mismatch.If a length limit cut off a text reply,
lms_chat_openai()warns with classrlmstudio_reply_cut_off. With aschema, a cut-off reply aborts.Every failed REST response now aborts with
rlmstudio_api_errorand the same message for the same response body. A 401 or 403 abort adds a hint about the API token.The server check now honors the
hostargument. Before, it always triedlocalhost:1234.list_models()no longer fails on a server with no models.has_lms()now findslmsin the same places aslms_path().A failed run of the LM Studio CLI or the headless installer now quotes its output in the abort message.
print()on a download status no longer showsNaN,Inf, or a percentage above 100. It prints each size in the unit that fits.A
POSIXltvalue in a request body no longer makes the call recurse with no end.The help of
lms_server_ready()no longer quotes one exact libcurl message for an emptyhost. The wording depends on the libcurl version, and the tests now pass with each wording.