1<!--
2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
3
4SPDX-License-Identifier: CC0-1.0
5-->
6
7# Rúmilo
8
9_Dedicated CLI research agent_
10
11[](https://api.reuse.software/info/git.secluded.site/rumilo)
12
13
14
15
16Query `rumilo` (or make an `rml` alias) in `web` or `repo` mode to have an LLM
17find an answer. Ask about ... anything! It knows the current date/time so it
18_can_ do a reasonable job at finding the latest version of `$thing`. It can find
19some tool's docs and provide usage instructions. It can read a library's source
20code to provide usage instructions.
21
22Use `web` mode to search the internet and read webpages. Provide a URL with `-u`
23to pre-fetch and attach that page. Rúmilo can still search/fetch if it decides
24that page isn't enough to answer the query.
25
26Use `repo` mode with a provided clone URI to clone the repo into a temporary
27directory and let the LLM do basic searching/listing/reading/etc. inside. If you
28or the main agent don't know the clone URI, use `web` mode to find it.
29
30You can use any model from any provider, remote or local. In theory. Rúmilo
31relies on [Pi] for all the LLM agenty things. Web search is _currently_ only
32through [Kagi] using [kagi-ken]. Kagi normally charge for API access, kagi-ken
33uses your existing subscription. Webpage fetching is _currently_ only handled by
34Mozilla's [Tabstack] service. It prefers cached copies if available, avoiding
35additional load on the destination site when possible. I intend to add some sort
36of extension system so it's easier to add support for any search/fetch provider.
37
38[Pi]: https://github.com/badlogic/pi-mono
39[Kagi]: https://kagi.com
40[kagi-ken]: https://github.com/czottmann/kagi-ken
41[Tabstack]: https://tabstack.ai
42
43## Usage
44
45```bash
46rumilo web "how do llm model loop werk?"
47rumilo web -u https://dev.synthetic.new/docs/openai/models "how should my client parse reasoning content?"
48rumilo repo -u https://github.com/synthetic-lab/octofriend "how does octo apply edits?"
49```
50
51## Requirements
52
53- [Bun]
54- [Git] (for repo mode)
55- Kagi session token (copy session link from [user details][kagi user details]
56 page, paste somewhere, your token is after `token=`)
57- Tabstack API key (log into [the console][tabstack console], and create a new
58 API key)
59
60[Bun]: https://bun.com
61[Git]: https://git-scm.com
62[kagi user details]: https://kagi.com/settings/user_details
63[tabstack console]: https://console.tabstack.ai
64
65## Configuration
66
67Rúmilo reads configuration from `$XDG_CONFIG_HOME/rumilo/config.toml`.
68
69Example:
70
71```toml
72[defaults]
73model = "anthropic:claude-sonnet-4-5"
74cleanup = true
75
76[web]
77model = "anthropic:claude-haiku-4-5"
78```
79
80### Custom Models
81
82You can define custom OpenAI-compatible endpoints like Ollama, vLLM, or
83self-hosted models in the `[custom_models]` section:
84
85```toml
86[custom_models.syn_glm47]
87provider = "synthetic"
88api = "openai-completions"
89base_url = "https://api.synthetic.new/openai/v1"
90api_key = "!fnox get SYNTHETIC_API_KEY"
91id = "hf:zai-org/GLM-4.7"
92name = "GLM 4.7"
93reasoning = true
94input = ["text"]
95cost = { input = 0, output = 0 }
96context_window = 198000
97max_tokens = 64000
98```
99
100Use custom models with the `custom:` prefix:
101
102```bash
103rumilo web "query" --model custom:syn_glm47
104rumilo repo -u <uri> "query" --model custom:syn_glm47
105```
106
107#### Custom Model Fields
108
109All custom model fields — including provider/API configuration, value resolution
110for `api_key` and `headers`, and OpenAI compatibility flags — are documented in
111[pi-mono's model configuration
112docs](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/models.md).
113That doc uses JSON; in Rúmilo's TOML config, field names use `snake_case`
114instead of `camelCase` (e.g. `base_url` instead of `baseUrl`, `context_window`
115instead of `contextWindow`).
116
117Compatibility flags go in a `[custom_models.<name>.compat]` sub-table:
118
119```toml
120[custom_models.mistral.compat]
121max_tokens_field = "max_tokens"
122requires_tool_result_name = true
123requires_thinking_as_text = true
124requires_mistral_tool_ids = true
125```
126
127**Note on `supports_developer_role`:** OpenAI's Responses API uses `role:
128"developer"` instead of `"system"` for reasoning models. Most OpenAI-compatible
129endpoints do not support this and will return "Incorrect role information"
130errors. If your custom model has `reasoning = true` and you encounter this
131error, set `supports_developer_role = false` in the compat section to use
132`"system"` instead.
133
134### Credentials
135
136Set credentials either via config (above) or environment:
137
138- `KAGI_SESSION_TOKEN`: Kagi session token
139- `TABSTACK_API_KEY`: Tabstack API key