{"id":51533229,"url":"https://github.com/diegomarino/opencode-lmstudio-warm","last_synced_at":"2026-07-09T05:30:25.071Z","repository":{"id":369280966,"uuid":"1289150565","full_name":"diegomarino/opencode-lmstudio-warm","owner":"diegomarino","description":"Deterministic LM Studio model pre-warm gate for opencode — loads and keeps the model resident before every request, healing cold starts and mid-session TTL evictions.","archived":false,"fork":false,"pushed_at":"2026-07-04T14:04:30.000Z","size":327,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-04T14:09:45.236Z","etag":null,"topics":["gemma","llm","lmstudio","local-llm","opencode","opencode-plugin","plugin","qwen","qwen3"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/diegomarino.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2026-07-04T11:41:54.000Z","updated_at":"2026-07-04T14:04:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/diegomarino/opencode-lmstudio-warm","commit_stats":null,"previous_names":["diegomarino/opencode-lmstudio-warm"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/diegomarino/opencode-lmstudio-warm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diegomarino%2Fopencode-lmstudio-warm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diegomarino%2Fopencode-lmstudio-warm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diegomarino%2Fopencode-lmstudio-warm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diegomarino%2Fopencode-lmstudio-warm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diegomarino","download_url":"https://codeload.github.com/diegomarino/opencode-lmstudio-warm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diegomarino%2Fopencode-lmstudio-warm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35288805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["gemma","llm","lmstudio","local-llm","opencode","opencode-plugin","plugin","qwen","qwen3"],"created_at":"2026-07-09T05:30:23.950Z","updated_at":"2026-07-09T05:30:25.045Z","avatar_url":"https://github.com/diegomarino.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# opencode-lmstudio-warm\n\nDeterministic model pre-warm for **opencode + LM Studio**.\n\n![Quick start: install the plugin, LM Studio starts cold, the first opencode run warms the model before the request leaves, and lms ps shows both models resident with no TTL](https://github.com/user-attachments/assets/f5522cb6-7967-4f47-a8c5-ca617a8d736a)\n\n\u003csup\u003eScripted demo (`tools/quickstart/generate-cast.py`) — every output line captured verbatim from a real run; the cold-load wait is shortened, and its spinner visualizes the plugin's background `lms load` (opencode itself waits silently).\u003c/sup\u003e\n\nA dependency-free opencode plugin that **guarantees your LM Studio model is\nloaded and addressable _before_ any request leaves opencode**.\n\nIf you point\nopencode at LM Studio, it fixes three failures you have probably already met:\n\n- **First request hangs** — the model is cold and JIT-loads while your request waits.\n- **`\"no model loaded\"` errors** — JIT is off and nothing loads the model for you.\n- **Mid-session breakage** — LM Studio's idle TTL evicted the model between two messages.\n\nPer request, the plugin checks that the model is actually loaded and, when it\nisn't, performs exactly one `lms load` (even across parallel sessions) before\nletting the request through.\n\nVerified against opencode **v1.17.10** and **LM Studio 0.4.18** (`lms` CLI\ncommit `6041ae0`) on macOS/Apple Silicon (see\n[`test/e2e/verify.sh`](./test/e2e/verify.sh), 9/9 passing). The LM Studio\nbehaviors the plugin depends on are the `lms ps --json` field names\n(`modelKey` / `identifier` / `status` / `queued`) and the fact that\n`lms load` is not idempotent.\n\n## Quick start\n\n**1. Install and register the plugin** — one command; opencode resolves it from\nnpm and adds it to your config's `plugin` array:\n\n```bash\nopencode plugin -g opencode-lmstudio-warm    # global (~/.config/opencode) — every session on the machine\n# or, for a single project's opencode.json:\nopencode plugin opencode-lmstudio-warm\n```\n\n**2. Point opencode at LM Studio** (skip if you already have an `lmstudio`\nprovider). In `~/.config/opencode/opencode.json`:\n\n```jsonc\n{\n  \"plugin\": [\"opencode-lmstudio-warm\"],\n  \"provider\": {\n    \"lmstudio\": {\n      \"npm\": \"@ai-sdk/openai-compatible\",\n      \"options\": {\n        \"baseURL\": \"http://127.0.0.1:1234/v1\",\n        \"apiKey\": \"{env:LM_API_TOKEN}\",\n        \"headerTimeout\": 600000,\n        \"chunkTimeout\": 120000\n      }\n    }\n  }\n}\n```\n\nThen set your `model` / `small_model` to your LM Studio model keys. See\n[`examples/opencode.json`](./examples/opencode.json) for a fuller starting point.\n\n**3. Adjust LM Studio once** (App Settings → Developer): disable\n**JIT model auto-unload TTL** and **unload previous JIT model on load**; keep\nJIT itself on as a fallback. ([Why these matter →](#how-it-works))\n\nThat's it — from your next opencode session, the model is warm before the\nfirst token is requested.\n\n## Install options\n\nAll three paths load the same plugin — pick the one that fits:\n\n| Path | Best for |\n|------|----------|\n| [npm](#npm-recommended) (recommended) | Most users and fleets — version-pinned, one-line updates |\n| [Single-file copy](#single-file-copy-offline-fleet-wide) | Offline machines |\n| [Project-local](#project-local) | Hacking on the plugin itself |\n\n### npm (recommended)\n\nThe Quick start command above is all you need. Notes:\n\n- You don't run `npm install` / `bun add` yourself, and there's no `npx` step —\n  opencode imports the module and auto-installs any plugin named in your config\n  at startup, so hand-adding `\"opencode-lmstudio-warm\"` to the `plugin` array\n  works too.\n- Use `-f` to force a version bump.\n\n**Scriptable setup** — for fleets or automation, this `jq` one-shot registers\nthe plugin *and* scaffolds the provider with recommended timeouts. It is\nidempotent and non-destructive: keeps your existing plugins, provider, and\nmodels, and never overwrites options you've set.\n\n```bash\nCFG=~/.config/opencode/opencode.json   # or ./opencode.json for a single project\n[ -f \"$CFG\" ] || echo '{}' \u003e \"$CFG\"\njq '\n  .plugin = ((.plugin // []) - [\"opencode-lmstudio-warm\"] + [\"opencode-lmstudio-warm\"])\n  | .provider.lmstudio.npm                  //= \"@ai-sdk/openai-compatible\"\n  | .provider.lmstudio.options.baseURL      //= \"http://127.0.0.1:1234/v1\"\n  | .provider.lmstudio.options.apiKey       //= \"{env:LM_API_TOKEN}\"\n  | .provider.lmstudio.options.headerTimeout //= 600000\n  | .provider.lmstudio.options.chunkTimeout  //= 120000\n' \"$CFG\" \u003e \"$CFG.tmp\" \u0026\u0026 mv \"$CFG.tmp\" \"$CFG\"\n```\n\n### Single-file copy (offline, fleet-wide)\n\n```bash\nmkdir -p ~/.config/opencode/plugin\ncp src/index.ts ~/.config/opencode/plugin/lmstudio-warm.ts\n```\n\nAuto-discovered by every opencode session on the machine. (opencode's docs spell\nthis directory `plugins`; verified as `plugin/` — singular — on v1.17.10.)\n\n### Project-local\n\nScope the plugin to a single project by copying `src/index.ts` into that\nproject's `.opencode/plugin/lmstudio-warm.ts` — opencode auto-discovers it there\nfor that project only. (This repo's own E2E fixture uses exactly this mechanism;\nsee `test/e2e/`.)\n\nWhichever path you pick, also apply the LM Studio GUI settings from\n[Quick start](#quick-start) step 3 on every machine. The provider timeouts\n(`headerTimeout` / `chunkTimeout`) are defense-in-depth and are already set by\nthe JSON/`jq` above.\n\n## Configuration\n\nThe plugin works with zero configuration. Optional tuning lives in\n`~/.config/opencode/lmstudio-warm.json` (or inline as\n`\"plugin\": [[\"opencode-lmstudio-warm\", {...}]]`).\n\n\u003e **Scope:** the plugin manages the **local** LM Studio through the `lms` CLI.\n\u003e `baseURL` (and any gated provider's `baseURL`) must point at this same\n\u003e machine — a non-loopback URL is logged as a warning, and the gate can\n\u003e neither verify nor load models on a remote server.\n\n| Option | Default | What it does |\n|--------|---------|--------------|\n| `providers` | `[\"lmstudio\"]` | Provider IDs to gate; requests on other providers are ignored. All listed providers must address the local LM Studio. |\n| `lmsPath` | `~/.lmstudio/bin/lms` if present, else `lms` | Path to the `lms` CLI. |\n| `baseURL` | `http://127.0.0.1:1234/v1` | Fallback base URL when the provider config doesn't carry one. Must be loopback. |\n| `ttlSeconds` | `0` | `--ttl` for `lms load`; `0` omits the flag (resident until unloaded). |\n| `parallel` | `0` | `--parallel` for `lms load`; `0` omits it (LM Studio default, currently 4). Size ≈ concurrent fleet width; overflow queues server-side. |\n| `contextLength` | `0` | `--context-length` for `lms load`; `0` omits it (model default). |\n| `perModel` | `{}` | Per-model-key overrides of `ttlSeconds` / `parallel` / `contextLength`. |\n| `verifyCacheMs` | `30000` | How long a positive residency verdict is trusted before re-checking. |\n| `retryCooldownMs` | `60000` | After a confirmed load failure, don't retry the same key for this long (prevents load storms). |\n| `loadTimeoutMs` | `900000` | Hard cap on a single `lms load` (a cold big-model load can take minutes). |\n| `serverStartTimeoutMs` | `90000` | Hard cap on bringing the HTTP server up. |\n| `lockWaitTimeoutMs` | `1200000` | Max wait for another process's in-flight load before proceeding fail-open. |\n| `failMode` | `\"hybrid\"` | `hybrid`: confirmed failures fail the request with a clear error, ambiguous ones proceed fail-open. `open`: never fail. `closed`: any warm failure fails the request. |\n| `reconcileDuplicates` | `true` | Unload idle suffixed duplicates (`key:2` …) and load fresh when the bare key isn't addressable. |\n| `launchAppFallback` | `true` | If the server won't start, try `open -ga \"LM Studio\"` once (macOS only). |\n| `eager` | `true` | Background-warm `model` + `small_model` at instance start. |\n| `evictOnPressure` | `false` | Opt-in RAM-pressure eviction: before loading a model that won't fit, unload **idle** instances (never busy, never the target, never protected) in LRU order to make room, then load. Off by default. See below. |\n| `ramBudgetMB` | `0` | RAM the fleet may use for LM Studio, in MB. `0` = auto (90% of total physical memory). The fit calc measures room against this — **not** `os.freemem()`, which under-reports available memory on macOS. |\n| `evictHeadroomMB` | `4096` | Flat safety margin (MB) added over a model's on-disk weight size when deciding whether it fits. Deliberately flat, not a KV-cache estimate (see note below); raise it for large `contextLength` / `parallel`. |\n| `evictProtect` | `[]` | Model keys (or instance identifiers) eviction must never unload. |\n| `evictMaxVictims` | `8` | Max instances eviction may unload per warm attempt (predictive + reactive combined). Caps worst-case lock-hold time; `0` = unlimited. |\n| `logFile` | `~/.cache/opencode/lmstudio-warm.log` | Plugin log file; rotated to `\u003clogFile\u003e.old` once it grows past ~5 MB. |\n| `lockDir` | `~/.cache/opencode/lmstudio-warm.lock` | Cross-process lock directory. |\n\n### RAM-pressure eviction (opt-in)\n\nOn a finite-RAM host running several large models, LM Studio with\n`modelLoadingGuardrails` set high **refuses** to load a model that doesn't fit\nrather than making room — so the target never loads and the request falls back\nto JIT or errors. Enable `evictOnPressure` to have the warm gate free room\nfirst. When a target model isn't resident and must be loaded, the gate:\n\n1. **Predictive pass** — looks up the target's weight size (`lms ls`), and if\n   it won't fit under `ramBudgetMB` (+ `evictHeadroomMB`), unloads idle\n   instances **least-recently-used first** until it fits, then loads.\n2. **Reactive backstop** — if the load is still refused for memory (weight size\n   is not the true runtime footprint), it frees the next idle instance and\n   retries, until the load succeeds or no idle instance remains.\n\nOnly **idle** instances are ever unloaded: anything generating or with queued\nwork is left alone, as is the target model and any key in `evictProtect`. A\nfresh check immediately before each unload re-confirms the victim is still idle.\nEverything runs under the same cross-process lock as loading, so concurrent\nwarm-gate workers don't over-commit RAM. At most `evictMaxVictims` instances are\nunloaded per attempt, bounding worst-case lock-hold time.\n\n\u003e **Best-effort, not atomic:** the pre-unload check and the `unload` itself are\n\u003e two separate `lms` commands, and the lock only coordinates this plugin's\n\u003e workers — not the LM Studio UI or other `lms` clients. So concurrent external\n\u003e use is **not** protected during eviction: a model can turn busy in the gap\n\u003e between check and unload, and a model being loaded by another client appears\n\u003e `idle` to `lms ps` (there is no ps-visible \"loading\" state). The window is\n\u003e narrow, but if you drive LM Studio from several places at once, prefer\n\u003e `evictProtect` for models you never want touched.\n\n\u003e **Why `evictHeadroomMB` is a flat number:** an accurate KV-cache estimate\n\u003e needs per-architecture internals (layers, KV heads, head dim) that `lms`\n\u003e doesn't expose, so any formula would be a false-precision guess. The reactive\n\u003e backstop absorbs under-prediction, so a flat margin that catches the gross\n\u003e case is enough. If loads are still refused with large context or parallelism,\n\u003e raise `evictHeadroomMB`.\n\nSee `examples/lmstudio-warm.json` for a fleet-tuned starting point\n(`cp examples/lmstudio-warm.json ~/.config/opencode/lmstudio-warm.json`).\n`perModel` keys are LM Studio model keys — the exact string opencode sends as\nthe API `model` field. Sizing `parallel`: set it to the expected number of\nconcurrent workers hitting that model; each slot costs extra KV-cache memory,\nand overflow requests queue server-side (latency, not failure), so\nundersizing is safe and oversizing wastes VRAM. Titles/summaries on the small\nmodel tolerate queueing; the main model is where fleet width matters.\n\n## Verify\n\nA live, self-contained E2E fixture lives in [`test/e2e/`](./test/e2e/) — set two\nreal LM Studio model keys and run it:\n\n```bash\nMAIN=\"your/main-model\" SMALL=\"your-small-model\" bun run e2e\n# requires jq, lms, opencode + a running LM Studio; export LM_API_TOKEN for full E2E\n```\n\nCovers: (a) cold spawn loads before the first request; (b) mid-session\neviction healed on resume (`opencode run -c`); (c) 3 parallel cold spawns →\nexactly one `lms load`, no `:2` duplicates; (d) orphaned `:2`-only state is\nreconciled back to an addressable instance. See\n[`test/e2e/README.md`](./test/e2e/README.md) for setup and the placeholders to edit.\n\n\u003e ⚠️ It mutates live LM Studio state (unloads/loads models, spawns parallel\n\u003e sessions) — run it on a dev machine, not a busy fleet.\n\n## Uninstall / rollback\n\nFor the npm install path, remove `\"opencode-lmstudio-warm\"` from the `plugin`\narray in `opencode.json`. For the file-copy paths:\n\n```bash\nrm ~/.config/opencode/plugin/lmstudio-warm.ts   # removes the gate everywhere\nrm -f ~/.config/opencode/lmstudio-warm.json     # optional tuning file\nrm -rf ~/.cache/opencode/lmstudio-warm.lock     # only if a stale lock lingers\n```\n\nModels loaded by the plugin have no TTL, so after uninstalling they stay\nresident until `lms unload \u003ckey\u003e` or an LM Studio restart. The `opencode.json`\ntimeout options and the LM Studio GUI settings are independent of the plugin\nand can stay.\n\n## How it works\n\n### The three layers\n\n1. **Plugin (primary, deterministic)** — `src/index.ts`.\n   Per request: verified-cache (30 s) → `lms ps --json` addressability check →\n   cross-process `mkdir` lock → double-checked re-check → orphan-duplicate\n   reconciliation → `lms load \u003ckey\u003e -y` (no `--ttl` ⇒ resident indefinitely,\n   `ttlMs: null` verified) → post-load verification. Plus a background eager\n   warm of `model` + `small_model` at instance start (`config` hook).\n2. **LM Studio server settings (independent)** — in the GUI (App Settings →\n   Developer): disable **JIT model auto-unload TTL** (`jitModelTTL`, the 1 h\n   eviction that stalls long sessions) and **unload previous JIT model on load**\n   (`unloadPreviousJITModelOnLoad` — otherwise a JIT load of one model can\n   evict the other). Keys live in `~/.lmstudio/settings.json` under\n   `developer.*` (edit only while the app is closed). Keep JIT **on** as a\n   fallback; keep server autostart on.\n3. **opencode timeouts (defense-in-depth)** — v1.17.10 honors undocumented\n   provider options `timeout`, `headerTimeout`, `chunkTimeout`\n   (`provider.ts:resolveSDK`). Default is NO timeout at all (infinite hang\n   possible). `opencode.json` here sets `headerTimeout: 600000` (tolerates\n   queueing behind busy parallel slots) and `chunkTimeout: 120000` (converts a\n   wedged stream into a visible, bounded error).\n\n### Why a plugin is the right layer (design decision)\n\nInvestigated against the v1.17.10 source (tag clone), not docs:\n\n- The `chat.params` hook is **awaited** (`yield* plugin.trigger(\"chat.params\", ...)`\n  in `session/llm/request.ts`) before every request is built and sent, and it\n  fires for **every** stream — including `small: true` title/summary requests.\n  One hook deterministically gates BOTH pinned models, per request, which is\n  what heals mid-session eviction (an orchestrator pre-warm only helps at\n  spawn time).\n- Plugins run in-process under Bun and can spawn `lms` (a blocking, exit-code\n  deterministic load barrier).\n- The `event` hook is dispatched fire-and-forget (`void hook.event?.(...)`) —\n  it can NOT gate. The v2 `ctx.aisdk.sdk` custom-fetch API is **types-only** in\n  v1.17.10 (nothing in core imports it) — that path from the prior verdict is\n  refuted for this release.\n- A plugin dropped in `~/.config/opencode/plugin/` is auto-discovered by every\n  worker on the machine — one file distributes fleet-wide and also covers\n  manually launched sessions.\n\nTradeoff vs. an orchestrator pre-warm node: the plugin costs one\n`lms ps --json` (~150 ms) per model per 30 s per process at steady state; the\norchestrator node is simpler but only covers spawn time and only sessions it\nspawns. Keep the orchestrator node, if you add one, as belt-and-suspenders —\nit is not required.\n\n## Known limitations / failure modes\n\n- **30 s verified-cache window**: an external unload (GUI, crash) within 30 s\n  of a positive check can slip one request through; it errors visibly and the\n  next request heals. There is no error hook in v1.17.10 to invalidate the\n  cache on failure.\n- **`lms ps` cannot signal \"loading\"** (measured: a loading instance shows\n  `status: \"idle\"` at ~200 ms into a 12.5 s load). A waiter can pass the gate\n  mid-load; LM Studio queues its request until weights are ready (verified) —\n  a short wait, not a failure.\n- **External JIT loads race**: a non-gated client can still trigger JIT\n  duplicates/evictions. Mitigated by Layer 2 settings; gate all fleet clients.\n- **`unloadPreviousJITModelOnLoad` scope for explicit loads is assumed exempt**\n  (evidence: explicit loads carry `ttlMs: null` vs JIT's TTL, so bookkeeping\n  differs). Confirm by JIT-loading a third model via API while both pinned\n  models are resident, then `lms ps`. Disabling the setting (Layer 2) makes\n  this moot.\n- **LM Studio app fully closed**: `lms server start` + `open -ga \"LM Studio\"`\n  fallback is implemented but untested here (the app was running). Confirm:\n  quit LM Studio → run one worker → check the log.\n- **Memory guardrails**: if LM Studio's guardrail refuses a load, the plugin\n  fails that request with a clear error and cools down 60 s (no load storm) —\n  it cannot free VRAM for you.\n- **API auth**: the plugin itself never needs `LM_API_TOKEN` (lms + probe are\n  auth-independent); workers still need it for generation when auth is on.\n\n## Running under an orchestrator (e.g. ao-lite)\n\nNo orchestrator changes are required — workers inherit the plugin from\n`~/.config/opencode/plugin/` and warm themselves. Two optional touches:\nexport `LM_API_TOKEN` in the worker environment (the plugin itself never needs\nit), and if you want spawn-time belt-and-suspenders, a pre-warm node only needs:\n`lms ps --json` guard → `lms load \u003ckey\u003e -y` — the same logic, but remember it\ncannot heal mid-session evictions; the plugin does.\n\n## Development\n\nThe plugin is a single file with **no runtime dependencies** (its only import,\n`@opencode-ai/plugin`, is `import type` and erased at build time). The root\n`package.json` pulls that type package and `@types/node` as devDependencies so\nyou can type-check locally:\n\n```bash\nbun install\nbun run typecheck        # tsc --strict, 0 errors\nbun run test             # vitest unit tests for the pure logic (test/)\nbun run check            # typecheck + tests + shellcheck\nbun run e2e              # live E2E fixture (needs LM Studio; see test/e2e/)\n```\n\nThe pure, per-process-stateless logic (config merge, model-ref parsing, load-arg\nbuilding, addressability, pid liveness, fail-mode decisions) is exported from\n`src/index.ts` and unit-tested under `test/`; the live system behavior is covered\nby the E2E fixture under [`test/e2e/`](./test/e2e/).\n\nReleases follow [SemVer](https://semver.org) and are cut automatically by\nsemantic-release on every push to `main` — Conventional Commits decide the\nbump (see [`CHANGELOG.md`](./CHANGELOG.md)).\n\n## Disclaimer\n\nCommunity plugin. Not affiliated with, endorsed by, or an official product of the\nOpenCode or LM Studio teams. \"opencode\" and \"LM Studio\" are used only to indicate\ncompatibility.\n\n## License\n\n[MIT](./LICENSE) © Diego Marino\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiegomarino%2Fopencode-lmstudio-warm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiegomarino%2Fopencode-lmstudio-warm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiegomarino%2Fopencode-lmstudio-warm/lists"}