Skill
Skills: Agent Skills folders any agent of their scope can attach.
check = noclick.Skill.from_dir("./skills/invoice-check") # SKILL.md plus its scripts and files
support = noclick.Agent.from_name("support", create_if_missing=True, instructions="...", skills=[check])A skill is a folder: a SKILL.md whose frontmatter names it (name) and
says what it does and when to use it (description; always: true puts it
whole in every turn), plus any other files. Every save is a new version; an
agent follows the latest unless it holds one (skill.pinned(3)). A coding
harness finds its skills where it reads skills; an sdk agent sees each
one's name and description every turn and reads one with skill__read.
class SkillAn Agent Skills folder of the account's (every user's agents may use it) or one user's, versioned. Delete it and it goes to the trash, off every agent that attaches it; restoring puts it back on them.
- Like every live object, it also has hydrate(), refresh() and raw.
| id | str | |
| name | str | Its name, from its latest |
| description | str | |
| always | bool | Whether it's put whole in every turn of the agents that attach it. |
| version | int | Its latest version's number. |
| digest | str | Its latest version's content as a digest: what restarts a coding agent's warm sandbox when it changes. |
| file_count | int | |
| size | int | Its latest version's size in bytes. |
| attached_to | list[SkillAttachment] | The agents that attach it, and the version each holds ( |
| user_id | str | None | |
| created_at | Any | |
| updated_at | Any |
createclassmethodasync
noclick.Skill.create(files, *, allow_existing=False, user=..., client=None) -> SkillA skill from its folder (path → text, or bytes for a file that isn't text), named by its SKILL.md;
unique by name to its user, or to the account outside as_user. A taken name raises
noclick.Conflict with existing_id, or with allow_existing=True returns the skill already
there as it is (save_version to change it). Up to 200 files and 20 MB, SKILL.md up to 64 KB.
FalseWho the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)The new skill at version 1.
check = noclick.Skill.create({
"SKILL.md": "---\nname: invoice-check\ndescription: Check an invoice against its purchase order.\n---\n1. ...",
"scripts/match.py": open("match.py").read(),
})from_dirclassmethodasync
noclick.Skill.from_dir(path, *, allow_existing=False, user=..., client=None) -> SkillA skill from a folder on this machine: its SKILL.md and every other file under it (.git,
__pycache__ and node_modules left out). A name already taken: as create.
FalseWho the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)The new skill (or, with allow_existing=True, the one already there).
check = noclick.Skill.from_dir("./skills/invoice-check")from_nameclassmethod
noclick.Skill.from_name(
name, *, create_if_missing=False, files=None, user=..., client=None
) -> SkillA lazy reference to the skill called name. Acting for a user, that
user's own skill is found first, then the account's. With
create_if_missing=True it's created from files on first use.
FalseNoneWho the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)A skill that loads (or is created) the first time it's used. Nothing is sent yet.
support = noclick.Agent.from_name("support", create_if_missing=True, instructions="...",
skills=[noclick.Skill.from_name("invoice-check")])from_idclassmethod
noclick.Skill.from_id(skill_id, *, client=None, user=...) -> SkillA lazy reference to a skill by id.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)Who the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
A skill that loads the first time you read a field. Nothing is sent yet.
skill = noclick.Skill.from_id(support.skills[0]["id"])getclassmethodasync
noclick.Skill.get(skill_id, *, user=..., client=None) -> SkillLoad a skill by id now; an unknown id raises noclick.NotFound.
Who the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)The skill, loaded: its latest version and the agents that attach it.
print(noclick.Skill.get(skill_id).attached_to)listclassmethodasync
noclick.Skill.list(
*, agent=None, limit=None, user_filter=None, user=..., client=None
) -> list[Skill]The current user's skills and the account's (or those user_filter covers), newest first. With
agent (an Agent or its id), the skills that agent attaches, in its order.
NoneReturn at most this many.
None)Which users a read covers: noclick.ALL_USERS, noclick.NO_USER, a User, or your id for one. It filters without acting as that user.
None)Who the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)Every matching skill, fetched page by page.
for skill in noclick.Skill.list():
print(skill.name, skill.version, [a.name for a in skill.attached_to])list_pageclassmethodasync
noclick.Skill.list_page(
*, cursor=None, limit=None, user_filter=None, user=..., client=None
) -> PageOne page of skills; pass next_cursor back as cursor.
The next_cursor of the page before; omit it for the first page.
None)Return at most this many.
None)Which users a read covers: noclick.ALL_USERS, noclick.NO_USER, a User, or your id for one. It filters without acting as that user.
None)Who the call acts for. Defaults to the user set by noclick.as_user (none: the account itself).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
None)A page whose data holds the skills and whose next_cursor is None on the last page.
page = noclick.Skill.list_page(limit=50)pinned
skill.pinned(version) -> SkillLinkThis skill held at one version, for an agent's skills=.
What skills= takes for a skill the agent holds at version.
noclick.Agent.from_name("support").update(skills=[noclick.Skill.from_name("invoice-check").pinned(3)])save_versionasync
skill.save_version(files, *, removed=(), replace=False, base_version=None) -> SkillSave a new version: files written over the latest (the whole folder with replace=True),
removed taken out. With base_version it saves only while the latest is still that version (else
noclick.Conflict). Agents following the latest get it in their next conversation; a running coding
sandbox restarts with it.
()FalseNoneThis skill, at its new version.
check = noclick.Skill.from_name("invoice-check")
check.save_version({"scripts/match.py": open("match.py").read()}, base_version=check.version)updateasync
skill.update(*, name=None, description=None) -> SkillRename it or change its description: a new version with its SKILL.md frontmatter rewritten.
NoneNoneThis skill, as it is now.
noclick.Skill.from_name("invoice-check").update(description="Check invoices and flag those over budget.")versionsasync
skill.versions() -> list[SkillVersion]Every version, newest first.
Each version's frontmatter, files, size and who saved it.
for v in noclick.Skill.from_name("invoice-check").versions():
print(v.version, v.created_by.type, v.created_at)get_versionasync
skill.get_version(version) -> SkillVersionOne version, with its files.
That version; an unknown one raises noclick.NotFound.
first = noclick.Skill.from_name("invoice-check").get_version(1)restoreasync
skill.restore(version) -> SkillA new version holding what version held.
This skill, at its new version.
noclick.Skill.from_name("invoice-check").restore(2)filesasync
skill.files(*, version=None) -> list[SkillFileInfo]The files of a version (the latest unless version), by path.
NoneEach file's path, size and hash.
print([f.path for f in noclick.Skill.from_name("invoice-check").files()])readasync
skill.read(path, *, version=None) -> SkillFileOne file of a version (the latest unless version): its text, or base64 when it isn't UTF-8.
NoneThe file; a path the version doesn't hold raises noclick.NotFound.
print(noclick.Skill.from_name("invoice-check").read("SKILL.md").content)deleteasync
skill.delete() -> TrashItemDelete it: to the trash, restorable for 30 days, and off every agent that attaches it until it's restored.
noclick.Skill.from_name("old-checks").delete()SkillAttachment
class SkillAttachmentAn agent that attaches a skill, and the version it holds (None: the latest).
| id | str | |
| name | str | |
| pin | int | None |
SkillAuthor
class SkillAuthorWho saved a version: a person in the app (console), a key (api), or an agent's turn.
| type | str | None | |
| agent_id | str | None | |
| agent_name | str | None |
SkillFile
class SkillFileOne file's content: its text, or base64 when it isn't UTF-8 (encoding).
| path | str | |
| version | int | |
| size | int | |
| sha256 | str | |
| content | str | |
| encoding | str |
SkillFileInfo
class SkillFileInfoOne file of a version, as its manifest lists it.
| path | str | |
| size | int | |
| sha256 | str |
SkillLink
class SkillLinkA skill held at one version on an agent (skill.pinned(n)).
| skill | Any | |
| pin | int |
SkillVersion
class SkillVersionOne version of a skill: its frontmatter as that version has it, and its files.
| version | int | |
| digest | str | |
| name | str | |
| description | str | |
| always | bool | |
| files | list[SkillFileInfo] | |
| size | int | |
| created_by | SkillAuthor | |
| created_at | Any | |
| raw | dict[str, Any] | The response JSON exactly as the API sent it. |