Skip to content
This repository was archived by the owner on Apr 29, 2026. It is now read-only.

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lm15

LM15.jl

One interface for OpenAI, Anthropic, and Gemini. Zero dependencies.

Julia implementation — conforms to the lm15 spec.

using LM15

result = call("gpt-4.1-mini", "Hello.")
println(text(result))

Install

using Pkg
Pkg.add(url="https://github.com/lm15-dev/lm15-jl")

Set at least one provider key:

export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export GEMINI_API_KEY=...

Usage

Blocking

result = call("gpt-4.1-mini", "Hello.")
println(text(result))
println(usage(result))
println(finish_reason(result))

Streaming

for chunk in stream(call("gpt-4.1-mini", "Write a haiku."))
    chunk.type == "text" && print(chunk.text)
end

Tools (auto-execute)

weather_tool = FunctionTool("get_weather", "Get weather by city",
    parameters=Dict{String,Any}(
        "type"=>"object",
        "properties"=>Dict{String,Any}("city"=>Dict{String,Any}("type"=>"string")),
        "required"=>["city"]),
    fn_=args -> "22°C in $(args["city"])")

result = call("gpt-4.1-mini", "Weather in Montreal?", tools=[weather_tool])
println(text(result))

Multimodal

using LM15

result = call("gemini-2.5-flash", "Describe this.",
    messages=[Message(role="user", parts=[
        TextPart("Describe this image."),
        ImageURL("https://example.com/cat.jpg"),
    ])])

Reasoning

result = call("claude-sonnet-4-5", "Prove √2 is irrational.", reasoning=true)
println(thinking(result))
println(text(result))

Conversation

conv = Conversation(system="You are helpful.")
user!(conv, "My name is Max.")
# ... pass conv.messages to call()

Cost tracking

configure!(track_costs=true)

result = call("gpt-4.1-mini", "Explain TCP.")
println(cost(result))

m = model("claude-sonnet-4")
println(text(call(m, "What is TCP?")))
println(text(call(m, "What is UDP?")))
println(total_cost(m))

configure!(track_costs=true) fetches pricing from models.dev. You can also call enable_cost_tracking!() directly, or use estimate_cost(usage, spec) / estimate_cost(usage, rates, provider) manually.

Reusable model

gpt = model("gpt-4.1-mini", system="You are terse.")
r1 = call(gpt, "Hello!")
r2 = call(gpt, "What did I say?")  # remembers conversation

Dump curl / HTTP request

using LM15

println(dump_curl("gpt-4.1-mini", "Hello.", env=".env"))
println(JSON.serialize(dump_http("gpt-4.1-mini", "Hello.", env=".env")))

Dependencies

Zero. Uses only Julia stdlib: Downloads for HTTP, Base64 for encoding, and a built-in JSON parser.

Architecture

call() / model()       ← high-level API
        │
        ▼
LMResult (lazy, streamable)
        │
        ▼
LMRequest → UniversalLM → Adapter → Downloads.request
                             │
                    providers/{openai,anthropic,gemini}.jl

Related

License

MIT

About

Archived: frozen pre-conformance Julia port. lm15-python2 is the active reference implementation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages