pomo-1

A LoRA fine-tune of LiquidAI/LFM2.5-230M for on-device to-do tool-calling. Given a short natural-language utterance and the user's current to-do list, pomo-1 emits a single structured tool call to create, update, or delete a to-do. Built to run locally on Apple Silicon via MLX.

This is a task-specific model, not a general assistant. It does one thing: turn an utterance + a small list of existing to-dos into one JSON tool call.

Intended use

  • In scope: single-turn to-do CRUD intent → one tool call, on-device.
  • Out of scope: multi-turn dialogue, reasoning, general chat, code, or any task the base model is not recommended for (advanced math, code generation, creative writing). Inherits the base model's limits.

Tools

tool arguments
create_todo title (str), due (str | null) — ignores the current list
update_todo target (str), title (str | null), due (str | null)
delete_todo target (str)
none {} — emitted when the referenced to-do is not in the list

For update_todo / delete_todo, target is a verbatim copy of one item in the provided list. If the referenced item is absent, the model emits none.

Prompt format

The current to-do list (0–5 items) is injected into the prompt. Training and inference must use this exact layout:

Todos:
- <todo 1>
- <todo 2>

User: <utterance>

An empty list renders as Todos:\n(none). Output is a JSON string, e.g.:

{"name":"delete_todo","arguments":{"target":"Book the moving truck"}}

Usage (MLX)

from mlx_lm import load, generate
from mlx_lm.sample_utils import make_sampler

model, tokenizer = load("<YOUR_HF_REPO>")  # e.g. sabeshbesh/pomo-1

prompt = "Todos:\n- Book the moving truck\n- Water the front yard plants\n\nUser: delete moving truck task"
tokens = tokenizer.apply_chat_template(
    [{"role": "user", "content": prompt}],
    add_generation_prompt=True, tokenize=True,
)
out = generate(model, tokenizer, prompt=tokens, max_tokens=96,
               sampler=make_sampler(temp=0.0))
print(out)  # {"name":"delete_todo","arguments":{"target":"Book the moving truck"}}

Greedy decoding (temp=0.0) is recommended for deterministic tool calls. The base model's general-purpose defaults are temperature 0.1, top_k 50, repetition_penalty 1.05.

Training

  • Base: LiquidAI/LFM2.5-230M (LFM2 hybrid: 14 layers, 8 gated short-conv + 6 GQA).
  • Method: LoRA SFT via mlx_lm.lora.
  • Adapter: rank 16, scale 16, dropout 0.05, applied to all 14 layers; mask_prompt: true.
  • Data format: legacy {"prompt", "completion"} JSONL; completion is a JSON-string tool call.
  • Hardware: Apple Silicon (MLX).

Evaluation

Held-out validation (n=300), best checkpoint, greedy decoding:

metric score
parse rate (valid JSON) 1.000
tool-name accuracy 0.997
argument exact-match 0.563
full match (name + args) 0.563

Metric definitions: parse rate = fraction of outputs that are valid tool-call JSON; tool-name accuracy = correct tool selected; argument exact-match = arguments exactly correct; full match = both correct.

Known limitation of this eval: these figures were measured on a dataset variant where the current to-do list was not included in the prompt, which makes correct target selection for update/delete structurally impossible in many cases — the argument/full-match scores are a floor, not a ceiling. No baseline comparison against the prior model is included. Treat these numbers as provisional.

License

Governed by the base model's license, lfm1.0. See the base model license.

Citation

Base model:

@article{liquidAI2026230M,
  author  = {Liquid AI},
  title   = {LFM2.5-230M: Built to Run Anywhere},
  journal = {Liquid AI Blog},
  year    = {2026},
  note    = {www.liquid.ai/blog/lfm2-5-230m}
}
Downloads last month
156
Safetensors
Model size
0.2B params
Tensor type
BF16
·
MLX
Hardware compatibility
Log In to add your hardware

Quantized

Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for sabeshbesh/pomo-1

Adapter
(4)
this model