Both Anthropic and OpenAI offer Skills management APIs (CRUD for provider-hosted skill bundles). The SDK supports skills at inference time via provider options, but not the management side (create, list, retrieve, update, delete). This would be the SDK's first non-inference provider API surface.
Provider comparison
Both providers share the same core model: upload files with a SKILL.md manifest via multipart form → get a skill ID for inference. Both support versioning (updating = creating a new version). Main differences: OpenAI has dual version pointers (latest_version + default_version, enabling staged rollouts), Anthropic has a single pointer (latest_version, new versions immediately active). Anthropic supports an optional display_title on create; OpenAI accepts only files.
References:
Impact on other future features
The decision making for how to implement this should not be done in isolation. There are several other, non-inference APIs that we've not yet supported through our abstraction and that are not connected to specific model APIs (e.g. uploading files). So we should consider a path that would be reasonable for those other features too.
Proposal
Add five experimental_ top-level functions to the ai package, following the existing pattern (public functions → spec interface → provider implementation):
import { experimental_createSkill, experimental_listSkills, experimental_retrieveSkill,
experimental_updateSkill, experimental_deleteSkill } from 'ai';
const skill = await experimental_createSkill({
provider: openai,
files: [{ path: 'SKILL.md', content: base64EncodedContent }],
});
await experimental_updateSkill({ provider: openai, skillId: skill.id, files: [...] });
await experimental_deleteSkill({ provider: openai, skillId: skill.id });
Architecture (three layers, no new packages):
@ai-sdk/provider: New SkillsManagerV1 interface + optional skillsManager?() on ProviderV3
@ai-sdk/openai / @ai-sdk/anthropic: Implement SkillsManagerV1
packages/ai/src/skills/: Top-level experimental_ functions that delegate to the provider's skills manager
Additional notes:
- Version management is hidden:
updateSkill creates a new version and promotes it to default internally. No version IDs exposed to users.
- We can consider adding version management in the future without breaking back-compat, but it feels too niche for the common use-case for adding complexity to the public API, at least for the start.
- Infrastructure needs: Add
deleteFromApi() to @ai-sdk/provider-utils (no DELETE utility exists today).
Open question: file content format
Currently files[].content would use DataContent (string = base64, consistent with existing SDK APIs like generateImage). But skill files are predominantly text (Markdown, Python), so base64 is somewhat awkward DX. Options:
- A)
mediaType field — { path: 'SKILL.md', content: '# My Skill', mediaType: 'text/markdown' }. Explicit but extra field.
- B) Auto-detect — heuristic to distinguish base64 from plain text (e.g. check for
data: prefix). Fragile.
- C) String = UTF-8,
Uint8Array = binary — best DX but departs from DataContent convention.
- D) Base64 only (leave as is) — consistent but worse DX for the common case.
Both Anthropic and OpenAI offer Skills management APIs (CRUD for provider-hosted skill bundles). The SDK supports skills at inference time via provider options, but not the management side (create, list, retrieve, update, delete). This would be the SDK's first non-inference provider API surface.
Provider comparison
Both providers share the same core model: upload files with a
SKILL.mdmanifest via multipart form → get a skill ID for inference. Both support versioning (updating = creating a new version). Main differences: OpenAI has dual version pointers (latest_version+default_version, enabling staged rollouts), Anthropic has a single pointer (latest_version, new versions immediately active). Anthropic supports an optionaldisplay_titleon create; OpenAI accepts only files.References:
Impact on other future features
The decision making for how to implement this should not be done in isolation. There are several other, non-inference APIs that we've not yet supported through our abstraction and that are not connected to specific model APIs (e.g. uploading files). So we should consider a path that would be reasonable for those other features too.
Proposal
Add five
experimental_top-level functions to theaipackage, following the existing pattern (public functions → spec interface → provider implementation):Architecture (three layers, no new packages):
@ai-sdk/provider: NewSkillsManagerV1interface + optionalskillsManager?()onProviderV3@ai-sdk/openai/@ai-sdk/anthropic: ImplementSkillsManagerV1packages/ai/src/skills/: Top-levelexperimental_functions that delegate to the provider's skills managerAdditional notes:
updateSkillcreates a new version and promotes it to default internally. No version IDs exposed to users.deleteFromApi()to@ai-sdk/provider-utils(noDELETEutility exists today).Open question: file content format
Currently
files[].contentwould useDataContent(string = base64, consistent with existing SDK APIs likegenerateImage). But skill files are predominantly text (Markdown, Python), so base64 is somewhat awkward DX. Options:mediaTypefield —{ path: 'SKILL.md', content: '# My Skill', mediaType: 'text/markdown' }. Explicit but extra field.data:prefix). Fragile.Uint8Array= binary — best DX but departs fromDataContentconvention.