Skills
Packaging a skill bundle and pushing new versions of it.
A skill is a bundle of knowledge and procedure that an agent can read. You upload it as an archive, and an agent version grants it by id.
The archive
A skill is a gzipped tar of the bundle directory, with SKILL.md at its root.
tar -czf skill.tar.gz -C ./refunds .
The SDK takes the bytes in whatever form you have them:
type SkillArchive = Uint8Array | Blob | ReadableStream<Uint8Array>;
Uploading
import { openAsBlob } from "node:fs";
const skill = await subako.skills.create(await openAsBlob("./skill.tar.gz"));
That creates the skill and its first version. Later versions go to the same skill:
await subako.skills.pushVersion(skill.skill_id, new Uint8Array(archive));
Each push is a new numbered version. Nothing is overwritten.
const versions = await subako.skills.listVersions(skill.skill_id, { limit: 20 });
const all = await subako.skills.list();
await subako.skills.rename(skill.skill_id, { name: "refunds-2026" });
await subako.skills.delete(skill.skill_id);
A stream is not retried
A request whose body is a ReadableStream cannot be read twice, so the SDK does not retry it. If you want the retries, pass a Blob or a Uint8Array instead — the SDK can replay those. See Timeouts and retries.
Granting it to an agent
The upload does not make the skill reachable. An agent version has to name it:
await subako.agents.publishVersion(agentId, {
model: { format: "anthropic", model: "claude-sonnet-5", max_tokens: 8192 },
skills: [
{ name: "refunds", skill_id: skill.skill_id, version: { type: "latest" } },
],
});
name is the label the model sees the skill under. The two version pins behave differently:
{ type: "latest" }?VersionPinBody
Resolved when each session is created, child sessions included. A session started after you push version 4 sees version 4; one already running stays where it was.
VersionPinBody{ type: "pinned", number: 3 }?VersionPinBody
Always that version. Pushing a new one changes nothing until you publish a config that names it.
VersionPinBodylatest is the one that surprises people: it does not update a live session, and it does not need a new agent version either. Pushing a skill version changes what tomorrow’s sessions read.