{"id":23265470,"url":"https://github.com/algunion/unilm.jl","last_synced_at":"2026-02-14T23:16:18.367Z","repository":{"id":179017516,"uuid":"662630535","full_name":"algunion/UniLM.jl","owner":"algunion","description":"UniLM.jl: Currently a Julia interface for OpenAI's (+Azure) language models, with the goal to become a unified solution for accessing multiple language models. While at the moment only OpenAI's models are supported, our vision is to evolve UniLM.jl into a versatile tool that simplifies the integration of diverse language models.","archived":false,"fork":false,"pushed_at":"2025-06-16T19:04:04.000Z","size":199,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-27T09:39:28.059Z","etag":null,"topics":["julia","llm","openai","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/algunion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-05T14:42:15.000Z","updated_at":"2025-06-16T19:04:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"849490c6-222c-43db-9402-7adc67816860","html_url":"https://github.com/algunion/UniLM.jl","commit_stats":null,"previous_names":["algunion/unilm.jl"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/algunion/UniLM.jl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algunion%2FUniLM.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algunion%2FUniLM.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algunion%2FUniLM.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algunion%2FUniLM.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/algunion","download_url":"https://codeload.github.com/algunion/UniLM.jl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algunion%2FUniLM.jl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29460230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T22:42:09.113Z","status":"ssl_error","status_checked_at":"2026-02-14T22:42:05.053Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["julia","llm","openai","wrapper"],"created_at":"2024-12-19T15:29:55.588Z","updated_at":"2026-02-14T23:16:18.362Z","avatar_url":"https://github.com/algunion.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UniLM.jl\n\n[![CI](https://github.com/algunion/UniLM.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/algunion/UniLM.jl/actions/workflows/CI.yml)\n[![codecov](https://codecov.io/gh/algunion/UniLM.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/algunion/UniLM.jl)\n[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)\n[![](https://img.shields.io/badge/%F0%9F%9B%A9%EF%B8%8F_tested_with-JET.jl-233f9a)](https://github.com/aviatesk/JET.jl)\n[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://algunion.github.io/UniLM.jl/stable/)\n[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://algunion.github.io/UniLM.jl/dev/)\n\nA **Julian**, type-safe interface to OpenAI's language models — covering both the classic **Chat Completions API**, the newer **Responses API**, **Image Generation**, and **Embeddings**. Designed to become a unified solution for accessing multiple LLM providers from Julia.\n\n## Features\n\n- **Chat Completions** — stateful conversations with automatic history management\n- **Responses API** — OpenAI's newer API with built-in tools, multi-turn chaining, and reasoning\n- **Image Generation** — create images from text prompts with `gpt-image-1.5`\n- **Tool/Function Calling** — first-class support for function tools in both APIs\n- **Embeddings** — text embedding generation with `text-embedding-3-small`\n- **Streaming** — real-time token streaming with `do`-block syntax\n- **Structured Output** — JSON Schema–constrained generation\n- **Multi-Backend** — OpenAI, Azure OpenAI, and Google Gemini\n- **Type Safety** — invalid states are unrepresentable; tested with [JET.jl](https://github.com/aviatesk/JET.jl) and [Aqua.jl](https://github.com/JuliaTesting/Aqua.jl)\n\n## Installation\n\n```julia\nusing Pkg\nPkg.add(url=\"https://github.com/algunion/UniLM.jl\")\n```\n\nOr in the Pkg REPL:\n\n```\npkg\u003e add https://github.com/algunion/UniLM.jl\n```\n\n## Quick Start\n\nSet your API key:\n\n```bash\nexport OPENAI_API_KEY=\"sk-...\"\n```\n\n### Responses API (recommended for new code)\n\n```julia\njulia\u003e using UniLM\n\njulia\u003e result = respond(\"Explain Julia's multiple dispatch in 2-3 sentences.\")\n\njulia\u003e output_text(result)\n\"Julia's multiple dispatch means a function can have many method definitions, and Julia chooses which one to run based on the types of *all* arguments in a call (not just the first). This makes it easy to write generic code while still getting specialized, high-performance behavior for specific type combinations.\"\n\njulia\u003e result.response.model\n\"gpt-5.2-2025-12-11\"\n```\n\n### Chat Completions\n\n```julia\njulia\u003e chat = Chat(model=\"gpt-4o-mini\")\n\njulia\u003e push!(chat, Message(Val(:system), \"You are a concise Julia programming tutor.\"))\n\njulia\u003e push!(chat, Message(Val(:user), \"What is multiple dispatch? Answer in 2-3 sentences.\"))\n\njulia\u003e result = chatrequest!(chat)\n\njulia\u003e result.message.content\n\"Multiple dispatch is a feature in programming languages, including Julia, that allows the selection of a method to execute based on the types of all its arguments, rather than just the first one. This enables more flexible and expressive code, as it can define different behaviors for a function depending on the combination of argument types. It supports polymorphism, making it easier to write generic code that works with multiple types.\"\n\njulia\u003e length(chat)  # system + user + assistant\n3\n```\n\n### One-Shot Convenience\n\n```julia\njulia\u003e result = chatrequest!(\n           systemprompt=\"You are a calculator. Respond only with the number.\",\n           userprompt=\"What is 42 * 17?\",\n           model=\"gpt-4o-mini\",\n           temperature=0.0\n       )\n\njulia\u003e result.message.content\n\"714\"\n```\n\n### Image Generation\n\n```julia\njulia\u003e result = generate_image(\n           \"A watercolor painting of a friendly robot reading a Julia programming book\",\n           size=\"1024x1024\", quality=\"medium\"\n       )\n\njulia\u003e result isa ImageSuccess\ntrue\n\njulia\u003e save_image(image_data(result)[1], \"robot_julia.png\")\n\"robot_julia.png\"\n```\n\n### Embeddings\n\n```julia\njulia\u003e emb = Embeddings(\"Julia is a high-performance programming language for technical computing.\")\n\njulia\u003e embeddingrequest!(emb)\n\njulia\u003e emb.embeddings[1:5]\n5-element Vector{Float64}:\n  -0.039474\n  -0.009283\n   0.001706\n  -0.028087\n   0.063363\n```\n\n### Streaming\n\n```julia\njulia\u003e task = respond(\"Write a haiku about Julia programming.\") do chunk, close\n           if chunk isa String\n               print(chunk)\n           elseif chunk isa ResponseObject\n               println(\"\\nDone! Status: \", chunk.status)\n           end\n       end\nMultiple dispatch sings,\nTypes align in swift fusion—\nLoops bloom into speed.\nDone! Status: completed\n```\n\n### Structured Output\n\n```julia\njulia\u003e fmt = json_schema_format(\n           \"languages\", \"A list of programming languages\",\n           Dict(\n               \"type\" =\u003e \"object\",\n               \"properties\" =\u003e Dict(\n                   \"languages\" =\u003e Dict(\n                       \"type\" =\u003e \"array\",\n                       \"items\" =\u003e Dict(\n                           \"type\" =\u003e \"object\",\n                           \"properties\" =\u003e Dict(\n                               \"name\" =\u003e Dict(\"type\" =\u003e \"string\"),\n                               \"year\" =\u003e Dict(\"type\" =\u003e \"integer\"),\n                               \"paradigm\" =\u003e Dict(\"type\" =\u003e \"string\")\n                           ),\n                           \"required\" =\u003e [\"name\", \"year\", \"paradigm\"],\n                           \"additionalProperties\" =\u003e false\n                       )\n                   )\n               ),\n               \"required\" =\u003e [\"languages\"],\n               \"additionalProperties\" =\u003e false\n           ),\n           strict=true\n       )\n\njulia\u003e result = respond(\"List Julia, Python, and Rust with their release year and primary paradigm.\", text=fmt)\n\njulia\u003e JSON.parse(output_text(result))\n{\n  \"languages\": [\n    {\"name\": \"Julia\", \"year\": 2012, \"paradigm\": \"Multi-paradigm (scientific/numerical, functional, concurrent)\"},\n    {\"name\": \"Python\", \"year\": 1991, \"paradigm\": \"Multi-paradigm (object-oriented, imperative, functional)\"},\n    {\"name\": \"Rust\", \"year\": 2010, \"paradigm\": \"Multi-paradigm (systems programming, functional, imperative)\"}\n  ]\n}\n```\n\n### Tool / Function Calling\n\n**Responses API:**\n\n```julia\njulia\u003e weather_tool = function_tool(\n           \"get_weather\", \"Get the current weather for a given location\",\n           parameters=Dict(\n               \"type\" =\u003e \"object\",\n               \"properties\" =\u003e Dict(\n                   \"location\" =\u003e Dict(\"type\" =\u003e \"string\", \"description\" =\u003e \"City name\"),\n                   \"unit\" =\u003e Dict(\"type\" =\u003e \"string\", \"enum\" =\u003e [\"celsius\", \"fahrenheit\"])\n               ),\n               \"required\" =\u003e [\"location\", \"unit\"],\n               \"additionalProperties\" =\u003e false\n           ),\n           strict=true\n       )\n\njulia\u003e result = respond(\"What's the weather in Tokyo? Use celsius.\", tools=[weather_tool])\n\njulia\u003e calls = function_calls(result)\n\njulia\u003e calls[1][\"name\"]\n\"get_weather\"\n\njulia\u003e JSON.parse(calls[1][\"arguments\"])\n{\"location\": \"Tokyo\", \"unit\": \"celsius\"}\n```\n\n**Web Search:**\n\n```julia\njulia\u003e result = respond(\n           \"What is the latest stable release of the Julia programming language?\",\n           tools=[web_search()]\n       )\n\njulia\u003e output_text(result)\n\"The latest **stable** release of the Julia programming language is **Julia v1.12.5**.\"\n```\n\n### Multi-Turn Conversations\n\n**Responses API** (via `previous_response_id`):\n\n```julia\njulia\u003e r1 = respond(\"Tell me a one-liner programming joke.\", instructions=\"Be concise.\")\n\njulia\u003e output_text(r1)\n\"There are only 10 kinds of people in the world: those who understand binary and those who don't.\"\n\njulia\u003e r2 = respond(\"Explain why that's funny, in one sentence.\", previous_response_id=r1.response.id)\n\njulia\u003e output_text(r2)\n\"It's funny because \\\"10\\\" looks like ten in decimal but equals two in binary, so it sets up a nerdy misdirection that only people who know binary immediately get.\"\n```\n\n## Multi-Backend Support\n\nUniLM.jl supports multiple backends. Switch via the `service` parameter:\n\n| Backend       | Type                    | Env Variables                                                               |\n| :------------ | :---------------------- | :-------------------------------------------------------------------------- |\n| OpenAI        | `OPENAIServiceEndpoint` | `OPENAI_API_KEY`                                                            |\n| Azure OpenAI  | `AZUREServiceEndpoint`  | `AZURE_OPENAI_BASE_URL`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_API_VERSION` |\n| Google Gemini | `GEMINIServiceEndpoint` | `GEMINI_API_KEY`                                                            |\n\n```julia\n# Azure\nchat = Chat(service=AZUREServiceEndpoint, model=\"gpt-5.2\")\n\n# Gemini\nchat = Chat(service=GEMINIServiceEndpoint, model=\"gemini-2.5-flash\")\n```\n\n## Two APIs, One Package\n\n| Feature                |       Chat Completions       |            Responses API            |\n| :--------------------- | :--------------------------: | :---------------------------------: |\n| Stateful conversations |       `Chat` + `push!`       |       `previous_response_id`        |\n| System prompt          | `Message(Val(:system), ...)` |        `instructions` kwarg         |\n| Tool calling           |  `GPTTool` / `GPTToolCall`   |  `FunctionTool` / `function_tool`   |\n| Web search             |              —               |           `WebSearchTool`           |\n| File search            |              —               |          `FileSearchTool`           |\n| Streaming              |   `stream=true` + callback   |          `do`-block syntax          |\n| Structured output      |       `ResponseFormat`       | `TextConfig` / `json_schema_format` |\n| Reasoning (O-series)   |              —               |             `Reasoning`             |\n\n## Documentation\n\nFull documentation with guides and API reference: **[https://algunion.github.io/UniLM.jl/dev/](https://algunion.github.io/UniLM.jl/dev/)**\n\n- [Getting Started](https://algunion.github.io/UniLM.jl/dev/getting_started/) — setup and first requests\n- [Chat Completions Guide](https://algunion.github.io/UniLM.jl/dev/guide/chat_completions/) — `Chat` and `chatrequest!`\n- [Responses API Guide](https://algunion.github.io/UniLM.jl/dev/guide/responses_api/) — the newer Responses API\n- [Image Generation Guide](https://algunion.github.io/UniLM.jl/dev/guide/image_generation/) — create images from text\n- [Tool Calling Guide](https://algunion.github.io/UniLM.jl/dev/guide/tool_calling/) — function calling\n- [Streaming Guide](https://algunion.github.io/UniLM.jl/dev/guide/streaming/) — real-time streaming\n- [Structured Output Guide](https://algunion.github.io/UniLM.jl/dev/guide/structured_output/) — JSON Schema output\n- [Multi-Backend Guide](https://algunion.github.io/UniLM.jl/dev/guide/multi_backend/) — Azure, Gemini\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgunion%2Funilm.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falgunion%2Funilm.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgunion%2Funilm.jl/lists"}