Skip to content
Roboto
Esc
↑↓navigate↵open⌘Jpreview
On this page

roboto.domain.skills

Stored, versioned procedures the chat AI can apply during a conversation.

A skill is text instructions the model follows when invoked — either manually via a chat-composer chip or automatically when the model selects it from the load_skill tool’s registry. Skills are owned by a user, optionally shared with the user’s organization, and versioned in place; each version is mutable without lifecycle states. Visibility and edit rights follow the skill’s accessibility: private (author-only), org (visible org-wide, author-only to edit), or org-editable (visible org-wide and editable by any subscribed member). Per-user subscriptions carry an ai_version pin that controls whether — and which version — the AI auto-invoke registry exposes to the subscriber.

Submodules

Package Contents

CreateSkillRequest

class roboto.domain.skills.CreateSkillRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Create a new skill plus its first version (version=1) in one call.

The author is auto-subscribed at creation time with ai_version set to 1 so the skill is immediately offered to the author’s AI.

Parameters

data Any

Attributes

CreateSkillRequest.accessibility

Visibility scope: Private (only the author), Org (visible to every org member, author-only to edit), or OrgEditable (visible to every org member, editable by any member who subscribes). The author can flip this later via UpdateSkillMetadataRequest.

CreateSkillRequest.body

body str #

Procedure text v1 — the instructions the model executes when this version is invoked. Bumping the version creates a new row; this field never re-edits v1’s body after the fact (use UpdateSkillVersionRequest for that).

CreateSkillRequest.description

description str = None #

“When to use” text for v1. Surfaces verbatim in the load_skill tool’s description so the model can decide whether to invoke this skill. Bumping the version replaces this text on the new row; this field never re-edits v1’s description after the fact.

CreateSkillRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

CreateSkillRequest.name

name str = None #

Skill name. Unique per org across every org-visible skill (Org and OrgEditable share one name namespace); private skills are unique per (org_id, created_by). A user’s private skill and an org-shared skill may therefore share a name without conflict. Must match SKILL_NAME_PATTERN so the name is parseable inside the chat composer’s /slug token (no whitespace, letters/digits/hyphens/underscores only).

CreateSkillRequest.relevant_topics

relevant_topics list[str] = None #

Topic names v1’s procedure investigates (e.g. "/imu/data"), supplied by the caller. Version-scoped content — see SkillVersionRecord.relevant_topics. The SDK stores the list as given; it performs no extraction. (The Roboto web UI populates it by scanning the body for [[topic]] references, but that is a UI convenience, not an SDK guarantee — a direct caller passes whichever names the procedure investigates.) Edit later via UpdateSkillVersionRequest.relevant_topics.

CreateSkillRequest.tags

tags list[str] = None #

Initial set of tags. Edits after creation flow through UpdateSkillMetadataRequest.put_tags / .remove_tags so concurrent updates merge cleanly — see SkillRecord.tags.

CreateSkillVersionRequest

class roboto.domain.skills.CreateSkillVersionRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Add a new version to an existing skill. The new version is assigned MAX(version) + 1.

Parameters

data Any

Attributes

CreateSkillVersionRequest.body

body str #

Procedure text the model executes when this version is invoked.

CreateSkillVersionRequest.description

description str = None #

“When to use” text for this version. Surfaces verbatim in the load_skill tool’s description on every turn this version is offered to the AI.

CreateSkillVersionRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

CreateSkillVersionRequest.relevant_topics

relevant_topics list[str] = None #

Topic names this version’s procedure investigates. Version-scoped content — see SkillVersionRecord.relevant_topics.

MAX_SKILL_DESCRIPTION_LENGTH

roboto.domain.skills.MAX_SKILL_DESCRIPTION_LENGTH = 500#View Source

SKILL_NAME_PATTERN

roboto.domain.skills.SKILL_NAME_PATTERN = '^[A-Za-z0-9_-]+$'#View Source

SetSkillSubscriptionRequest

class roboto.domain.skills.SetSkillSubscriptionRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Upsert the caller’s subscription for a skill.

Idempotent: creates the subscription row if missing, otherwise updates ai_version in place. Visibility-gated only — the caller does not need to be the skill’s author. The server enforces that ai_version, if provided, references an existing version of the skill.

Parameters

data Any

Attributes

SetSkillSubscriptionRequest.ai_version

ai_version int | None = None #

Pinned AI-available version. None means “subscribed, but not exposed to AI”.

SetSkillSubscriptionRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Skill

class roboto.domain.skills.Skill(record, roboto_client)#View Source

An AI skill — a versioned, accessibility-scoped procedure the chat AI can apply.

Use create() to create a new skill, from_id() / from_name() to load existing ones, and list_for_org() to iterate. The constructor is internal.

Skill.create()

classmethod create(name, description, body, accessibility=SkillAccessibility.Private, tags=None, relevant_topics=None, caller_org_id=None, roboto_client=None)#View Source

Create a new skill plus its first version (version=1).

The skill is created in the caller’s organization. With the default SkillAccessibility.Private accessibility only the caller can see, edit, or delete it. SkillAccessibility.Org makes it readable by all org members (author-only to edit); SkillAccessibility.OrgEditable additionally lets any member who subscribes edit its versions, name, and tags. The author is auto-subscribed at creation time and the new version is pinned as Available to AI. Other org members must subscribe() to see the skill in their AI auto-invoke registry. Pass tags to seed the skill’s tag list at creation time; later edits flow through UpdateSkillMetadataRequest. Pass relevant_topics to record the topic names v1’s procedure investigates; the chat AI resolves them to schemas when it loads the skill (see SkillVersionRecord.relevant_topics).

Usage

skill = Skill.create(
    name="qa-review",
    description="Run when the user asks for a QA review of a dataset.",
    body="Step 1: load the dataset summary...",
    accessibility=SkillAccessibility.Org,
    tags=["qa-review", "triage"],
    relevant_topics=["/imu/data", "/gps/fix"],
)
skill.skill_id
# 'sk_...'

Parameters

name str
description str
body str
tags Optional[collections.abc.Sequence[str]]
relevant_topics Optional[collections.abc.Sequence[str]]
caller_org_id Optional[str]
roboto_client Optional[roboto.http.RobotoClient]

Return type

Skill.create_version()

create_version(request)#View Source

Add a new version to this skill. The server assigns MAX(version) + 1.

Permitted for the author and — on an SkillAccessibility.OrgEditable skill — for any subscribed org member. Subscribers who pinned the previous version stay on that pin until they explicitly re-pin — the new row does not auto-promote.

Pass relevant_topics to record the topic names this version’s procedure investigates; the chat AI resolves them to schemas when it loads the skill (see SkillVersionRecord.relevant_topics).

Usage

v2 = skill.create_version(
    CreateSkillVersionRequest(
        description="Run when ...",
        body="Updated procedure ...",
        relevant_topics=["/imu/data", "/gps/fix"],
    )
)
v2.version
# 2

Properties

Skill.created_by

created_by str #
Return type: str

Skill.delete()

delete()#View Source

Hard-delete this skill. Author-only, including on OrgEditable skills.

Cascades to all versions and subscriptions. Existing chats keep any fabricated load_skill tool_use / tool_result blocks they’ve already produced — the body is captured at invocation time and written into the transcript.

Usage

skill.delete()

Return type

None

Skill.delete_version()

delete_version(version)#View Source

Delete a single version. If it’s the last remaining version, the parent skill is removed too.

Permitted for the author and — on an SkillAccessibility.OrgEditable skill — for any subscribed org member. A subscribed non-author may not delete the last remaining version: that cascades into a full skill delete, which is author-only. The author has no such restriction.

Subscriptions pinned to the deleted version have their ai_version nulled out via a server-side trigger; the subscription row survives.

Usage

skill.delete_version(1)

Parameters

version int

Return type

None

Skill.from_id()

classmethod from_id(skill_id, roboto_client=None)#View Source

Load a skill by its skill_id.

Parameters

skill_id str
roboto_client Optional[roboto.http.RobotoClient]

Raises

No skill with this id exists, or the caller cannot see it (visibility-gated).

Return type

Usage

skill = Skill.from_id("sk_abc123")
skill.name
# 'qa-review'

Skill.from_name()

classmethod from_name(name, caller_org_id=None, roboto_client=None)#View Source

Load a skill by name in the caller’s organization.

Skill names are unique within (org_id, accessibility). When both a private and an org-shared skill share a name in the same org, this method returns the caller’s private one (the manual-invocation tie-break — see SkillsRepo.get_skill_by_name()).

Parameters

name str

Skill name. URL-encoded by the SDK.

caller_org_id Optional[str]

Look up in this org. Defaults to the caller’s current org.

roboto_client Optional[roboto.http.RobotoClient]

Raises

No skill with this name is visible to the caller in the target org.

Return type

Usage

skill = Skill.from_name("qa-review")
skill.accessibility
# <SkillAccessibility.Org: 'org'>

Skill.get_summary()

classmethod get_summary(skill_id, roboto_client=None)#View Source

Load one skill’s summary: the skill, its latest version, and your subscription.

The single-skill counterpart of list_for_org(). Prefer it over filtering that listing when you already know the skill_id — it costs one row instead of the whole org’s skills.

Parameters

skill_id str
roboto_client Optional[roboto.http.RobotoClient]

Raises

No skill with this id exists, or the caller cannot see it (visibility-gated, same as from_id()).

Usage

summary = Skill.get_summary("sk_abc123")
summary.latest_version.version
# 3
summary.subscription is None  # not subscribed
# True

Skill.get_version()

get_version(version)#View Source

Load a specific version of this skill.

Parameters

version int

Raises

No such version exists.

Usage

v2 = skill.get_version(2)
print(v2.body)

Skill.list_for_org()

classmethod list_for_org(scope=None, caller_org_id=None, roboto_client=None)#View Source

Yield SkillSummary items for every skill the caller can see in their org.

The summary includes the latest version (MAX(version)) and the caller’s own subscription row when one exists. When scope is provided the result is restricted to either Personal (authored or subscribed) or Org (org-shared skills the caller did not author, regardless of subscription state). Omit scope to receive every visible skill in one stream.

Usage

List the caller’s Personal-tab skills:

for summary in Skill.list_for_org(scope=SkillListScope.Personal):
    print(summary.skill.name, summary.subscription.ai_version if summary.subscription else None)

Iterate every visible skill (Personal + Org), in one pass:

all_visible = list(Skill.list_for_org())

Parameters

caller_org_id Optional[str]
roboto_client Optional[roboto.http.RobotoClient]

Return type

collections.abc.Generator[roboto.domain.skills.record.SkillSummary, None, None]

Skill.list_known_tags()

classmethod list_known_tags(caller_org_id=None, roboto_client=None)#View Source

Return the distinct tags found on skills the caller can see in this org.

Visibility-filtered the same way list_for_org() is — private skills owned by other users contribute no tags. Suitable for powering a tag-autocomplete UI.

Usage

Skill.list_known_tags()
# ['qa-review', 'triage', 'experiments']

Parameters

caller_org_id Optional[str]
roboto_client Optional[roboto.http.RobotoClient]

Return type

list[str]

Skill.list_versions()

list_versions()#View Source

List every version of this skill, newest first.

Usage

for version in skill.list_versions():
    print(version.version, version.description)

Properties

Skill.name

name str #
Return type: str

Skill.org_id

org_id str #
Return type: str

Skill.refresh()

refresh()#View Source

Re-fetch this skill’s record from the server and return self.

Useful after another caller may have updated the skill — bumps the local view past stale data.

Usage

skill.refresh()
skill.name  # now reflects any server-side rename
# 'qa-review'

Return type

Skill.set_ai_version()

set_ai_version(version)#View Source

Pin (or clear) which version of this skill the AI auto-invokes for the caller.

Pass an integer to expose that exact version to AI auto-invocation; pass None to disable AI auto-invocation while keeping the subscription. Implicitly subscribes the caller if no row exists yet. Visibility-gated; the caller does not have to be the author.

Usage

Pin version 2 for AI auto-invoke:

skill.set_ai_version(2)

Stop the AI from auto-invoking this skill, but stay subscribed so manual chip-invocation still works:

skill.set_ai_version(None)

Parameters

version Optional[int]

Properties

Skill.skill_id

skill_id str #
Return type: str

Skill.subscribe()

subscribe()#View Source

Subscribe to this skill — adds it to the caller’s Personal tab.

Idempotent: if the caller is already subscribed (or is the author), the existing row is returned unchanged. New subscriptions default to ai_version=None (not yet exposed to AI). Use set_ai_version() to enable AI auto-invocation.

Usage

sub = skill.subscribe()
sub.ai_version is None
# True

Properties

Skill.tags

tags list[str] #
Return type: list[str]

Skill.unsubscribe()

unsubscribe()#View Source

Remove the caller’s subscription row — removes the skill from their Personal tab.

No-op if there is no subscription. Authors who unsubscribe from their own skill can re-subscribe later; authorship is unchanged.

Usage

skill.unsubscribe()

Return type

None

Skill.update_metadata()

update_metadata(request)#View Source

Update skill-level metadata (name, accessibility, tags).

Editing the name and tags is permitted for the author and — on an SkillAccessibility.OrgEditable skill — for any subscribed org member. Changing accessibility is always author-only.

Updates apply in place; the local record is replaced with the server’s authoritative copy.

Usage

skill.update_metadata(
    UpdateSkillMetadataRequest(
        accessibility=SkillAccessibility.Org,
        put_tags=["qa-review"],
    )
)

Skill.update_version()

update_version(version, request)#View Source

Edit fields on an existing version in place.

Permitted for the author and — on an SkillAccessibility.OrgEditable skill — for any subscribed org member.

Subscribers pinned to this version see the new body on their next AI invocation; there is no per-edit revision. Use create_version() when callers should not be auto-migrated.

Usage

skill.update_version(2, UpdateSkillVersionRequest(body="..."))

SkillAccessibility

class roboto.domain.skills.SkillAccessibility#View Source

Bases: roboto.compat.StrEnum

Controls who can see and edit a skill.

Attributes

SkillAccessibility.Org

Org = 'org' #

All members of the owning org can see and invoke the skill. Only the author can edit.

SkillAccessibility.OrgEditable

OrgEditable = 'org-editable' #

All members of the owning org can see and invoke the skill, and any member who has subscribed to it can also edit its versions, name, and tags. Changing the skill’s accessibility and deleting the whole skill remain author-only.

SkillAccessibility.Private

Private = 'private' #

Only the author (created_by) can see, edit, or invoke the skill.

SkillListScope

class roboto.domain.skills.SkillListScope#View Source

Bases: roboto.compat.StrEnum

Which caller-relative slice of the visible skills a list-skills query targets.

Attributes

SkillListScope.Org

Org = 'org' #

Org-shared skills authored by someone else, regardless of whether the caller has subscribed.

SkillListScope.Personal

Personal = 'personal' #

Skills the caller authored or has subscribed to — their personal set.

SkillRecord

class roboto.domain.skills.SkillRecord(/, **data)#View Source

Bases: pydantic.BaseModel

Top-level skill identity, ownership, and visibility.

A skill on its own carries no procedure content — see SkillVersionRecord.

Parameters

data Any

Attributes

SkillRecord.accessibility

accessibility SkillAccessibility #

SkillRecord.created

created datetime.datetime #

SkillRecord.created_by

created_by str #

SkillRecord.modified

modified datetime.datetime #

Last edit timestamp. Skill mutations are author-only, so the editor is always created_by — no separate modified_by field is stored.

SkillRecord.name

name str #

SkillRecord.org_id

org_id str #

SkillRecord.skill_id

skill_id str #

SkillRecord.tags

tags list[str] = None #

Free-form labels for categorization (e.g. "qa-review", "experiments"). Skill-level metadata, not version-scoped — they describe what the skill is for, not how a specific version implements it. Edited via the changeset fields on UpdateSkillMetadataRequest (put_tags / remove_tags).

SkillSubscriptionRecord

class roboto.domain.skills.SkillSubscriptionRecord(/, **data)#View Source

Bases: pydantic.BaseModel

Per-user state for a single skill.

Created when a user subscribes to a skill (or authors one — authors are auto-subscribed at create time). Carries the user’s choice of which version, if any, should be exposed to the AI auto-invoke registry. ai_version=None means the user is subscribed but has not enabled the skill for AI auto-invoke; manual chip-invocation still works.

Parameters

data Any

Attributes

SkillSubscriptionRecord.ai_version

ai_version int | None = None #

If set, the AI’s LoadSkillTool registry surfaces this exact version of the skill to this user. If None, the skill is hidden from AI auto-invocation for this user. Manual invocation works regardless.

SkillSubscriptionRecord.skill_id

skill_id str #

SkillSubscriptionRecord.subscribed

subscribed datetime.datetime #

When the subscription was created.

SkillSubscriptionRecord.user_id

user_id str #

SkillSummary

class roboto.domain.skills.SkillSummary(/, **data)#View Source

Bases: pydantic.BaseModel

Compact projection of a skill plus its latest version (if any).

Also includes the caller’s personal subscription state for the skill, when one exists. subscription=None means the caller has neither authored nor subscribed to the skill.

Parameters

data Any

Attributes

SkillSummary.latest_version

latest_version SkillVersionRecord | None = None #

The MAX(version) row for this skill. Always populated for summaries returned from the public API: Skill.create() makes the skill row and v1 atomically, and deleting the last version cascades to delete the parent skill in the same transaction. The Optional is defense-in- depth for repo-direct callers (test fixtures, manual SQL) and should not be treated as a real branch by SDK consumers.

SkillSummary.skill

SkillSummary.subscription

subscription SkillSubscriptionRecord | None = None #

The caller’s subscription row for this skill, if any. Populated by the server based on the caller’s identity; not used in INSERT or UPDATE payloads.

SkillVersionRecord

class roboto.domain.skills.SkillVersionRecord(/, **data)#View Source

Bases: pydantic.BaseModel

A single, mutable version of a skill’s content.

Parameters

data Any

Attributes

SkillVersionRecord.body

body str #

The procedure text the model executes when the skill is invoked.

SkillVersionRecord.created

created datetime.datetime #

SkillVersionRecord.description

description str = None #

Short ``when to use’’ text. Surfaces verbatim in the LoadSkillTool description.

SkillVersionRecord.modified

modified datetime.datetime #

SkillVersionRecord.relevant_topics

relevant_topics list[str] = None #

Topic names this version’s procedure investigates (e.g. "/imu/data").

Version-scoped content, not skill-level metadata — they track the body, so a new version may reference a different set. When the chat AI loads this skill and is given a dataset scope, it resolves each name to a topic schema and returns them alongside the body in the same load_skill tool result, sparing a follow-up get_topic_schema turn. Names only; field-level references live in the body text. Empty when the author listed none.

SkillVersionRecord.skill_id

skill_id str #

SkillVersionRecord.version

version int #

UpdateSkillMetadataRequest

class roboto.domain.skills.UpdateSkillMetadataRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Update top-level skill identity.

Editing name / put_tags / remove_tags is permitted for the author and — on an OrgEditable skill — for any subscribed org member. Changing accessibility is always author-only.

Parameters

data Any

Attributes

UpdateSkillMetadataRequest.accessibility

New visibility scope. Omit to leave unchanged. Author-only — a subscribed non-author editor of an OrgEditable skill cannot change it. Flipping Private → Org / OrgEditable immediately exposes the skill to every org member; flipping to Private prunes every non-author subscription.

UpdateSkillMetadataRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

UpdateSkillMetadataRequest.name

name str | roboto.sentinels.NotSetType = None #

New skill name. Omit (the NotSet default) to leave unchanged. Must match SKILL_NAME_PATTERN and stays unique per org (private skills per author).

UpdateSkillMetadataRequest.put_tags

put_tags list[str] = None #

Tags to add. Empty (the default) means “no change to tags.” Additive semantics — does not clear other tags.

UpdateSkillMetadataRequest.remove_tags

remove_tags list[str] = None #

Tags to remove. Empty (the default) means “no change to tags.” Removing a tag the skill doesn’t have is a no-op.

UpdateSkillVersionRequest

class roboto.domain.skills.UpdateSkillVersionRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Edit fields on an existing version (mutates in place).

Parameters

data Any

Attributes

UpdateSkillVersionRequest.body

New procedure text. Omit (the NotSet default) to leave unchanged. The change applies in place to this version — subscribers pinned to it will see the new body on their next AI invocation; there is no per-edit revision.

UpdateSkillVersionRequest.description

description str | roboto.sentinels.NotSetType = None #

New “when to use” text. Omit (the NotSet default) to leave unchanged.

UpdateSkillVersionRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

UpdateSkillVersionRequest.relevant_topics

relevant_topics list[str] | roboto.sentinels.NotSetType #

New topic-name list. Omit (the NotSet default) to leave unchanged; pass an empty list to clear all topics. Version-scoped content — see SkillVersionRecord.relevant_topics.

Was this page helpful?