hobkin
A small unattended agent: one process per agent, run through plain files. A hobkin is a little hob, the house spirit that does the chores while the house sleeps.
- One file, standard library only.
hobkin.py, Python 3.12+. Nothing to install. - No ports. It listens on nothing; it only makes outgoing calls to the model API.
- Files are the interface. Talk to it with
echo, watch it withtail -F, and see exactly what the model sees withcat. - Many per account. Each agent has its own id and folder, and a lock stops two processes running the same one.
Install
pipx install hobkin # or: uv tool install hobkin
That gives you the hobkin command. Python 3.9 or newer on Linux (or another
POSIX system); no dependencies. You can also skip installing and run the file
directly: python3 hobkin.py.
Quick start
One line, no config editing: the API's URL, the model, your key.
pipx install hobkin
hobkin https://openrouter.ai/api/v1 anthropic/claude-sonnet-4.5 sk-or-... --chat
That:
- checks the key works and the API offers that model (a typo gets the close
names back;
--forceskips the check for APIs that don't list their models); - sets it up as your default model in
~/.hobkins/_shared/config.json, with the key in_shared/keys/, readable only by you. Leave the key out and it asks for it, so it stays out of your shell history; leave it out for a local server with none; - starts a new agent as a systemd user service (see "Keeping agents running"),
or in the background where there's no systemd (or with
--no-service); - with
--chat, connects you to it. Without, it prints how.
The API style comes from the URL (anthropic.com is Anthropic's; anything else is
OpenAI-style: OpenRouter, vLLM, llama.cpp, Ollama's /v1, LiteLLM...); --api
overrides it. --id NAME names the agent instead of a random id. Run it again with
another URL or model to add that one and make it the default.
To see what an API offers before choosing: hobkin models URL [KEY]; hobkin models
lists your configured model's API, and /models does the same in a chat.
The long way:
hobkin # a new agent: prints its id, e.g. 7f3a91c2
hobkin 7f3a91c2 # resume that agent later (its context is kept)
The first run creates ~/.hobkins/_shared/config.json. Set your model there (see
Models) and make sure the API key is reachable.
Then, from another terminal, chat with it:
hobkin chat 7f3a91c2
Its output appears as it comes, and each line you type (or paste) is sent;
/stop and the other commands work, and Ctrl-D leaves. Output never wipes out
what you're typing (the line is redrawn below it), and you get the usual line
editing: ↑/↓ for earlier messages (kept in the agent's .chat_history),
←/→, Ctrl-R to search. Piped, it sends the
input, prints the reply and exits: echo "status?" | hobkin chat 7f3a91c2.
Or with plain files:
echo "Clone https://example.com/repo and get its tests passing" > ~/.hobkins/7f3a91c2/in
tail -F ~/.hobkins/7f3a91c2/out
Run it in the background however you like: nohup hobkin 7f3a91c2 &,
tmux, or a systemd user service.
An agent's folder
~/.hobkins/ID/ (or $HOBKIN_HOME/ID/):
| File | What it is |
|---|---|
in |
A named pipe. echo text > in sends a message. A write waits until the agent is running; hobkin send ID text queues it instead. |
out |
Everything it says and does since the last compaction, with timestamps: messages, commands, output. At each compaction it's moved to archive/ and starts afresh. tail -F out |
context.jsonl |
Exactly what the model is sent: line 1 is the system prompt, then one message per line. Rewritten after every change. |
MEMORY.md |
The agent's own notes. Part of its instructions on every turn, and kept when the conversation is compacted. Past 80 lines, it's told to prune. |
BLOOPERS.md |
Its blooper reel: its own mistakes, told for laughs, each with the lesson. Also part of its instructions every turn, so the jokes double as lessons learned. Past 30 lines, it's told to keep the best. |
state.json |
Model, context window (and where that number came from), status, pid, compaction count. |
work/ |
Its working directory. |
reminders.json |
Its reminders (when, message, repeat). Readable and editable by hand. |
shell.sh |
Its shell's saved state (folder, variables, functions, aliases), restored before each command. Secrets are never saved here. |
secrets.env |
Optional KEY=value lines, set as environment variables in its shell (never put in its context). |
config.json |
Optional per-agent settings over the shared ones. |
*.md |
Optional per-agent instructions; replace shared files of the same name. |
archive/ |
At each compaction, the old conversation (context-*.jsonl, messages only) and its out log (out-*.log). Deleted after 30 days, except the newest. |
jobs/ |
Background jobs' output and exit codes; a finished job's folder goes after 30 days. |
queue, lock |
Messages sent while it was stopped; the process lock. |
~/.hobkins/_shared/ holds what all agents share: config.json, AGENTS.md (how
to work as a hobkin: a task routine with checklists, failure handling,
organization, memory and tidying up; created on first run, edit freely: it's never
overwritten, so new defaults reach it only if you delete it), an optional SOUL.md,
any other .md instructions, and secrets.env.
The system prompt is:
SOUL.md, thenAGENTS.md, then the other.mdfiles in name order;- the list of skills (see below);
MEMORY.md.
Each .md file is taken from the agent's folder if it has one, otherwise from
_shared/. The prompt is rebuilt every turn, so edits take effect on the next one.
Skills
Skills use the same format as Claude Code and other agents: a folder holding a
SKILL.md with a name and description in its front matter, plus any scripts
or reference files. Install one by copying its folder into
~/.hobkins/_shared/skills/, and every agent can use it.
~/.hobkins/_shared/skills/agent-tickets/SKILL.md
~/.hobkins/_shared/skills/release/SKILL.md
~/.hobkins/_shared/skills/release/build.sh
The prompt lists only each skill's name and description. When a task calls for
one, the agent opens it with the skill tool. That gives it the instructions,
the skill's folder as a full path, and its list of files, so it never has to
work out where scripts live. Dozens of skills cost a line each.
- An agent's own
skills/folder can add skills, or replace a shared one with the same name. skill_dirsin config adds more folders at the lowest priority, e.g.["~/.claude/skills"]to reuse skills you already have.- New skills are picked up on the next turn; no restart needed.
Talking to it
Anything you write to in is a message. The agent sees it labelled with who
sent it and when: set "operator": "frank" in config.json (use the name people know
you by, e.g. your tracker username) and it reads [message from frank, Sat 2026-10-17 09:12], with its system prompt saying who that is; without it,
[message from operator, …]. After a quiet spell it adds how long it's been
(; 3d 2h since you last worked), so Friday's request isn't mistaken for
today's. Automatic messages are marked and timed too ([from hobkin: idle prompt, …], [Reminder #3 …], finished jobs), so the agent never mistakes
them for you. If it's busy running a command, the
message is added to the result of that command, marked "[message from
operator]". A line that is just one of these is a command instead:
| Command | Effect |
|---|---|
/stop |
Finish cleanly and exit (Ctrl-C and SIGTERM do the same). |
/pause, /resume |
Stop and restart work; messages wait until /resume. |
/interrupt |
Kill the command it's running now (it's told it was interrupted). |
/compact |
Summarise and clear the conversation now. |
/status |
Write its status to out. |
/reminders |
Write its reminders to out. |
/veto |
Block every announced command that's waiting to run (see "Announce first"). |
/model [NAME] |
Alone: the model in use and the ones configured. With a name: switch to that configured model, or to any model the agent's API offers (it gets a config entry like the current one). Saved in the agent's config.json, so it lasts; happens between steps. |
/models |
List the models the agent's API offers (the one in use starred), with their context windows. |
/limits |
Ask the API for the context window again (it's also re-asked before every compaction and after a "too long" error, so a window that grew or shrank is noticed). |
/restart |
Once the current step is done, start over in the same process on the code on disk now (after a git pull or pip install -U), and carry on. The agent can send it itself: a repeating reminder can pull and restart. |
hobkin chat ID puts both in one terminal (see Quick start). hobkin list shows all agents, their status and their last line of output.
Models
config.json names the model to use and describes each one:
{
"model": "claude",
"models": {
"claude": {"api": "anthropic", "base_url": "https://api.anthropic.com",
"model": "claude-sonnet-5-5", "key_env": "ANTHROPIC_API_KEY", "key_file": "~/.anthropic.key"},
"openrouter": {"api": "openai", "base_url": "https://openrouter.ai/api/v1",
"model": "anthropic/claude-sonnet-5.5", "key_file": "~/openrouter.key"},
"local": {"api": "openai", "base_url": "http://127.0.0.1:8080/v1", "model": "local-model"}
}
}
model picks one of models. The models are exactly the ones in your config
files (the three above are only the starter file), so a model you delete is
gone. An agent's own config.json can add models, or change settings on a
shared one (e.g. its requests_per_minute), and can pick a different model.
If model names one that isn't defined, hobkin stops and lists the ones that
are; if it's left out and there's only one model, that one is used.
api:anthropic(the Messages API) oropenai(Chat Completions: OpenAI, OpenRouter, vLLM, llama.cpp, Ollama, ...).- The key comes from the environment variable
key_env, or else from the filekey_file. It's removed from the agent's shell environment. headers(optional): extra HTTP headers.thinking(optional):"adaptive", a token budget (8000), or the API's own object. Anthropic only; it must be smaller thanmax_output_tokens.effort(optional):"low"to"max". It goes to Anthropic asoutput_config.effort, to OpenRouter asreasoning.effort, and to other OpenAI-style APIs asreasoning_effort.extra_body(optional): anything else your provider takes, merged into every request as is.prompt_cache(optional): on OpenAI-style APIs, mark the system prompt and the newest message for caching. It's on by default for Claude models (e.g. on OpenRouter), where re-reading the conversation then costs about 5% of the normal input price; a test session went from about $0.023 per call to $0.001. On OpenRouter, each call's reported cost is added up instate.json(spend_usd).requests_per_minute(optional): a cap on calls to this model. It's shared by every agent using the same API, model and key, because that's what the provider counts. The agents coordinate through a small lock file in_shared/(holding a hash of the key, never the key). An agent at the cap waits, and still answers commands such as/stopwhile it does.
When the provider rate-limits anyway (HTTP 429):
- It waits exactly as long as the API says. It reads
Retry-After(seconds or a date), OpenRouter'sX-RateLimit-Reset, Anthropic'santhropic-ratelimit-*-reset, and reset times inside the error body, then waits until then plus a second. - If the API gives no reset time, it waits 15 seconds, then 30, 60…, up to 5 minutes. A 40-second limit costs two blocked calls at most.
- The cooldown is shared. The first agent to hit a 429 records "blocked until
…" in
_shared/, and every other agent on the same API, model and key waits it out without trying, so a team causes one blocked call, not one each. - It's visible:
- the log says
rate limited by the API; the API said when (retry-after): waiting 41s (until 13:42:10); state.jsonsayswaiting (rate limited);- the heartbeat says
waiting out a rate limit (until 13:42:10)./stopand the other commands still work while it waits.
- the log says
The context window is asked for, not hard-coded. At start-up hobkin asks the API:
- Anthropic:
GET /v1/models/{model}(max_input_tokens,max_tokens). - OpenAI-style: the
/modelslist (context_lengthas on OpenRouter,max_model_lenas on vLLM, and similar). - llama.cpp's
/propsand Ollama's/api/show.
context_tokens on a model is optional: set it and that number is used as
given; leave it out (or null) and it's detected. If the API doesn't say,
set it. Failing that, hobkin
learns the limit from the first "context too long" error and remembers it.
Windows can change (a local server restarted with a different size): the API is
asked again before each compaction, after a "too long" error that doesn't say the
limit, and on /limits.
state.json records where the number came from.
When the conversation passes compact_at (80%) of the window, the agent writes
itself a handoff note. The conversation is replaced by that note, with the
newest unanswered message carried over unchanged, and the old conversation goes to
archive/ (messages only: the system prompt is rebuilt every turn anyway), along
with out, which starts afresh. The note tells the agent where the archive is,
so it can grep it.
Fallback models: "fallback_models": ["other", "local"] (names from
models) are tried in order when the model refuses outright: withdrawn,
renamed, a bad key, out of credit. Free models on OpenRouter come and go, so
it's worth having one. Busy and rate-limited models are waited out instead. A
restart goes back to model.
Typos and wrong types in config.json are reported at startup (in out and on
stderr), with suggestions such as "unknown setting 'idel_seconds' (did you mean
'idle_seconds'?)". They're warnings; nothing is refused.
Other settings (shared or per agent): bash_timeout (600 s per command by
default; the agent can ask for any longer timeout on a command),
output_limit (30,000 characters of command output, head and tail kept),
max_output_tokens (16,000, capped at what the API reports), and
idle_prompt / idle_seconds (see below).
Its tools
bashruns as your user, starting inwork/. It behaves like one shell that stays open:- The first command runs as a login shell (your profile's PATH and so on).
- After every command, its state is saved to
shell.sh: the folder, variables, exports, functions and aliases. The next command starts from that state. Socd,exportandsource .venv/bin/activatecarry over, even across restarts. - Each command is still its own process, so a hung or crashed command can't
take the shell's state with it. Shell options like
set -edon't carry over. reset: truestarts a fresh login shell inwork/.- Every result ends with the folder it's now in.
- The environment has
secrets.envplusHOBKIN_ID,HOBKIN_DIR,HOBKIN_WORKandHOBKIN_MEMORY.
read_fileshows a file with line numbers (in pages), or lists a folder.write_filewrites a whole file.edit_filereplaces one exact piece of text. The text goes in as is, with no shell quoting, which is where smaller models most often go wrong.- Errors are written to help: "appears 2 times (lines 3, 5)", or the closest matching lines when the text isn't found.
- Line numbers pasted from
read_fileare stripped automatically, and Windows line endings are handled. - Paths are relative to the shell's folder;
$HOBKIN_WORK,$HOBKIN_MEMORYand~work.
remindsets a reminder to wake itself later, andreminderslists or cancels them (see below).skillopens a skill by name.view_imageshows it an image (PNG, JPEG, GIF, WebP, under 5 MB): a screenshot of the UI it built, a chart, a photo. On OpenAI-style APIs the image follows the tool result as a user message, because tool messages can't hold images.fetch_urlreads a web page as text: headings, lists and tables kept, scripts and menus' styling dropped, links numbered with a list at the end. Long pages come in parts (offset,limit), JSON is pretty-printed, andsave_asdownloads anything else (a PDF, an image) into the workspace.web_searchsearches DuckDuckGo and returns the top ten results: title, URL, snippet.
The web
Normal sites need no setup. For an internal wiki behind a client certificate (PEM files), set it in config:
"web": {
"client_cert": {"cert": "~/certs/me.pem", "key": "~/certs/me.key",
"ca": "~/certs/corp-ca.pem", "password_file": "~/certs/key-password"}
}
- One certificate for everything: it's offered to any site that asks for
one, including SSO servers along a redirect chain. Most public sites never ask.
ca(your internal CA, trusted alongside the usual ones) andpassword_fileare optional. - SSO logins that need no typing are followed: redirects, meta refreshes,
and the auto-submitting forms that SAML and OpenID logins use (up to 8 steps).
Cookies are kept in the agent's
cookies.txt, so the next page skips the login. A login that wants a password shows up as the login page's text. - Pages built by JavaScript come back nearly empty. Give the agent a skill for those (an API, or a headless browser).
- Search uses DuckDuckGo's HTML page (
web.search_url, no key). DuckDuckGo sometimes answers servers and VPNs with a "bots use DuckDuckGo too" check instead of results; the agent is told so, and searching from a home connection usually works. To check a machine:curl -s -A Mozilla/5.0 -d q=test https://html.duckduckgo.com/html/ | grep -c result__a(a number above 0 means results).
Background jobs
bash with background: true returns at once ("background job #3 started"),
and when the job ends the agent gets a message with its exit code, how long it
took, and the last of its output. Jobs run detached in the shell's current
state, with their output in jobs/N/out.log. They outlive a hobkin restart: a
job that finished while hobkin was stopped is reported when it starts again.
That suits builds, test suites, downloads, and "naps", where a job switches off
a local model, uses the GPU, and starts the model again: nothing calls the model
while the job runs, and its end wakes the agent.
Announce first
Commands whose effects leave the machine are announced before they run:
- What counts (
announce_firstin config, a name and a regex each): force pushes, pushes to main, publishing packages, releases, image pushes, infrastructure changes, cloud deletions, and sending email or webhook messages. - The first try isn't run. hobkin tells the agent to post what it's about to
do and why where people will see it, then run the same command again with
announcedset. - Then it waits
announce_delay(2 minutes), long enough for someone to object in chat. After that, the same command runs. - To stop it, send
/veto, which blocks everything waiting. Or just object where it posted: the agent is told to check before it runs the command.
Everything else, anything inside the box, needs no announcement.
Daily budget
daily_budget_usd pauses an agent for the rest of the day once it has spent
that much. First it gets one last turn to say so where people will see it.
Spend counts only where the API reports each call's cost (OpenRouter does);
state.json keeps spend_today and the all-time spend_usd.
Nothing asks for approval: an agent can do anything your account can. Agents in one account stay apart by convention (their own folders), not by enforcement. Use a separate account or container when that matters.
Reminders
An agent can schedule its own wake-ups: remind with in ("20m", "2h",
"1h30m"), or at (local time: "2026-10-17 09:00", "09:00" for the next one,
"tomorrow 09:00"), optionally every to repeat. The reply states the exact
time it will fire, because small models are bad at time arithmetic. When it's
due, the agent gets a message: "[Reminder #3, set … for …. It's now …]" and
then its own text.
- Idle: it wakes straight away.
- Mid-task: nothing is interrupted. The reminder arrives with the result of the step in progress (after a long command finishes, for example), like your own mid-task messages.
- Paused: it waits until
/resume. - While hobkin wasn't running: it's delivered at the next start, marked late. A repeating one is delivered once, saying how many times were missed, and moves to its next time.
- No limits. Any number of reminders, repeating as often as it likes, even
every second. A repeating reminder that has fallen behind is delivered once,
with a count of how many times it was missed, so it can't flood the agent.
Using
everywhereinwas meant is the classic slip, so the reply points that out. reminders.jsonis a plain file: read it, edit it, or delete entries. The agent's current reminders are also listed in its system prompt.
Keeping agents running
Reminders and idle prompts only fire while the agent's process runs. An idle hobkin costs nothing (it sleeps; no API calls), so keep agents up as systemd user services:
hobkin service add tickets-1 # start it now, and at every boot
hobkin service remove tickets-1 # stop it and take it off boot
add does all of this:
- It writes one template unit,
~/.config/systemd/user/hobkin@.service, shared by all agents. - It points that unit at the hobkin you ran it with (the installed command, or
python3 /path/hobkin.py). - It enables and starts
hobkin@tickets-1. - It turns on linger, so agents keep running when you're logged out. If your system won't allow that without a password, it tells you the command to run.
hobkin list shows which agents run as services.
- Stopping and crashes:
/stopexits cleanly and stays stopped. A crash is restarted after 30 seconds, and systemd gives up after 5 failures in 10 minutes, so a broken config can't spin. - Logs: the agent's own log stays in its
outfile. The journal (journalctl --user -u hobkin@ID) gets startup errors, plus a heartbeat everyheartbeat_seconds(60) while the agent is on duty:hobkin ID active: workingwhile it works;hobkin ID active: on duty, next check in 7m (reminder #2)while it's idle with a wake-up scheduled (say, a tracker check with nothing to pick up).- It's silent while only a message can wake the agent, or when it's paused, so
a quiet journal means it's waiting for you. There's no heartbeat in a
terminal; set
heartbeat_secondsto 0 to turn it off.
- Alerts: when an agent pauses on its own (a model error, the daily budget)
or falls back to another model, it may not be able to say so itself. Set
alert_commandto a shell command and it runs with the news in$HOBKIN_ALERTand the agent'ssecrets.envin its environment, e.g.curl -s -H "Authorization: Bearer $TICKETS_TOKEN" --data-urlencode "text=$HOBKIN_ALERT" https://tickets.example/api/comment. - Keys: a service doesn't see your shell's environment.
key_fileworks as is; forkey_env, putNAME=valuelines in~/.config/hobkin/env(chmod 600).addwarns when that's needed. - Another
HOBKIN_HOMEgets its own template (hobkin-<hash>@.service), so homes never clash.
Waking up when idle
Hobkins don't nap. After idle_seconds (60) of quiet, an idle agent gets
idle_prompt, labelled [from hobkin: idle prompt]. The default is "You're
idle. Unacceptable! Grab work from your work sources, or hunt for something
useful to do." It stays quiet while the agent has a reminder set or a background
job running. Set idle_prompt to null to let it rest until a message or
reminder arrives. Each nudge is a model call, so pair a short idle_seconds
with a requests_per_minute you're happy with.
The gremlin
The default AGENTS.md makes a hobkin a relentlessly cheerful, work-greedy, cheeky little gremlin:
- Forgiveness over permission. It acts, then says what it did.
- Good enough beats better. It ships the working version and moves on.
- The opposite of a yes-man. It laughs at bad ideas, its own included, and does the better thing.
- Hot takes. It rates each task out of five stars.
- Never fakes success.
Small models skim long instructions, so hobkin also nudges at the moment each behaviour matters:
- A message from you carries a reminder to give a hot take first (a hello or a question just gets answered).
- A clear slip (a file-tool error, a command that wasn't found) gets a nudge towards the blooper reel.
- Writing that loses its voice (a reply, or a
.md/.txtfile, heavy with committee words like "robust", "comprehensive", "production-ready") gets "that reads like a committee wrote it", once per turn. - A file read only partly ends with how many lines are still unread, so the agent doesn't fill the rest in from imagination.
- When a working turn ends, there's one wrap-up check: did you report where the people are, any bloopers, more work to grab? It's sent once per turn, so it can't loop.
Busy or self-managing agents get no chatter. If the agent has set up its own next wake-up (a reminder, or a background job still running), the hot take, the wrap-up check and the idle nag stay quiet; it's clearly managing itself. A message that arrives mid-task gets no hot-take reminder either. The corrective nudges (echo, slips, committee voice, unread lines) still apply, since they cost nothing extra.
All of it is plain text in hobkin.py and AGENTS.md, so rein it in as you like.
As an agent-tickets worker
Nothing in hobkin knows about agent-tickets; you give it the instructions and the token:
hobkin # note the id, then /stop it (Ctrl-C)
ID=7f3a91c2 URL=http://127.0.0.1:43917 TOKEN=the-token-for-this-agent
printf 'AGENT_TICKETS_URL=%s\nAGENT_TICKETS_TOKEN=%s\n' "$URL" "$TOKEN" > ~/.hobkins/$ID/secrets.env
chmod 600 ~/.hobkins/$ID/secrets.env
curl -s -H "Authorization: Bearer $TOKEN" "$URL/api/skill" --create-dirs \
-o ~/.hobkins/_shared/skills/agent-tickets/SKILL.md
echo '{"idle_prompt": "Run the agent-tickets wait loop (GET /api/wait) and do what it says.", "idle_seconds": 60}' \
> ~/.hobkins/$ID/config.json
hobkin $ID
The agent-tickets skill is shared: it reads the token from
AGENT_TICKETS_TOKEN, so one copy serves every worker, each with its own
secrets.env. The idle prompt keeps it
checking for work, and it can also hold /api/wait open itself inside a
command. Give each worker its own token, so claims and comments show which
agent did what.
Releasing
Releases go to PyPI from GitHub Actions with Trusted Publishing (no token stored):
- Bump
__version__inhobkin.py, commit and push. - Publish a GitHub release tagged
vX.Y.Z(matching__version__). The workflow runs the tests on Python 3.9, 3.12 and 3.14, builds, checks the tag matches, and uploads to PyPI.
Running the workflow by hand (Actions → Publish → Run workflow) uploads to TestPyPI instead, for a dry run.
Measuring behaviour
The tests check that hobkin works; tests/eval_hobkin.py checks how well an agent
behaves on it, so changes to AGENTS.md or the nudges can be measured, not
eyeballed. It runs a real model (it costs calls; free models are fine) through
six scenarios with a tiny work system (a queue, a team chat, a skill) and scores
what it does:
| Scenario | What it checks |
|---|---|
queue |
does the job, ticks it off, reports in the team chat |
badidea |
rates your bad idea, pushes back, keeps sane filenames |
memory |
does work its stale memory says isn't there, and fixes that memory |
hello |
answers a hello, with no rating, no busywork, no talking through echo |
reading |
finds an answer far beyond the first page of a file |
slow |
doesn't block on a command longer than the timeout |
Most scenarios also check that it didn't ask what to do and kept its workspace tidy.
python3 tests/eval_hobkin.py --model nvidia/nemotron-3.5-super-vl:free \
--key-file ~/openrouter.key --runs 3 # --only queue,hello for some
It prints a line per run and a score per check across runs (e.g. queue 2/3 reported in the team chat). Run it before and after a change.
Tests
python3 tests/test_hobkin.py
These start real hobkin processes against tests/fake_api.py: a local
stand-in for both APIs that rejects malformed conversations. So the tests cost
nothing and don't need a key. They cover both API styles:
- commands, secrets, and hiding the model key from the shell;
- live and queued messages, the lock,
/interrupt, messages arriving mid-command; - stopping and resuming, and recovery after a crash mid-command;
- compaction, learning the window from an error, and the newest request surviving compaction;
- the shell's saved state (variables, arrays, functions, aliases, PATH, folder,
login profile,
reset), with secrets never saved; - the file tools (exact text with quotes,
$and backslashes; repeated and missing matches; pasted line numbers; paging) and the skill tool; - skills (listing, which copy wins, front matter);
requests_per_minuteshared across two agents;- reminders (firing while idle, arriving mid-command with that command's result,
validation, list and cancel, the prompt section, late and repeating after a
restart, a broken
reminders.json).
Metadata
Release files for hobkin 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hobkin-0.2.1.tar.gz | 99.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hobkin-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 165.5 kB
Release files / hobkin-0.2.1.tar.gz
| Download URL | hobkin-0.2.1.tar.gz |
|---|---|
| Size | 99.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a74d63138bea731a118675535831cda26266ae84c19d457e433d617398e5c4bc
|
|
BLAKE2b-256 checksum How to use checksums |
d5e35e2639503749b3b12f7bf13a3bdd9a14368f07c7ae05d777c6d8dcfcf705
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / hobkin-0.2.1-py3-none-any.whl
| Download URL | hobkin-0.2.1-py3-none-any.whl |
|---|---|
| Size | 65.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44e0001d09f31add663a6ede42e881d7b649dc4cbe0723ea031255390e4e2fd1
|
|
BLAKE2b-256 checksum How to use checksums |
3d1de6a1093aeb77654e133b3a407155b190e8f4c6e4c3dea468ab04cd1a266b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for hobkin 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for hobkin-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.