Use skills
Sync skill content into the workspace and attach it to a PromptPack so the model can activate skills on demand.
You create a SkillSource, publish a PromptPack version that lists it in spec.skills, then check that the agent pod loads the manifest.
Prerequisites
Section titled “Prerequisites”- Workspace content storage. The chart enables it, and the operator receives
--workspace-content-path(default/workspace-content). - A PromptPack from a ConfigMap, already running on an AgentRuntime.
- A
kubectlthat can reach the workspace namespace (dev-agentsbelow).
Step 1: create a SkillSource
Section titled “Step 1: create a SkillSource”Save as skills.yaml. The repository URL, tag and skill names are illustrative; use your own.
apiVersion: omnia.altairalabs.ai/v1alpha1kind: SkillSourcemetadata: name: support-skills namespace: dev-agentsspec: type: git git: url: https://github.com/anthropic/skills ref: { tag: v1.4.0 } interval: 1h targetPath: skills/anthropic filter: include: ["ai-safety", "pdf-processing"]Apply it and wait for the first fetch:
kubectl apply -f skills.yamlkubectl get skillsource support-skills -n dev-agents -wThe source is synced when PHASE is Ready and SKILLS matches the filtered set. Then check that every retained SKILL.md parsed:
kubectl get skillsource support-skills -n dev-agents \ -o jsonpath='{.status.conditions[?(@.type=="ContentValid")]}'status: "True" means every SKILL.md parsed and no two skills in the source share a name.
See SkillSource for the oci and configmap source types and every filter field.
Step 2: attach to a PromptPack
Section titled “Step 2: attach to a PromptPack”A published PromptPack version is immutable, so kubectl patch on spec.skills is rejected. Publish a new version that lists the source. Save as pack-v2.yaml:
apiVersion: omnia.altairalabs.ai/v1alpha1kind: PromptPackmetadata: name: support-pack-1-1-0 namespace: dev-agentsspec: packName: support-pack version: "1.1.0" source: type: configmap configMapRef: name: support-pack-prompts # the ConfigMap your current version uses skills: - source: support-skills include: ["ai-safety"] mountAs: compliance skillsConfig: maxActive: 5To offer the model only some skills, add selector: tag and a tags list under skillsConfig. A skill is offered when its SKILL.md metadata tags shares an entry with that list.
kubectl apply -f pack-v2.yamlAn AgentRuntime that pins promptPackRef.version keeps serving the old version until you change the pin.
The PromptPack controller resolves the references, writes a JSON manifest into the workspace content volume, and sets three conditions:
kubectl get promptpack support-pack-1-1-0 -n dev-agents \ -o jsonpath='{range .status.conditions[*]}{.type} {.status} {.reason}{"\n"}{end}'| Condition | Reason when True | Meaning |
|---|---|---|
SkillsResolved | AllSkillsResolved | Every spec.skills[].source exists and has synced |
SkillsValid | NoCollisions | No two referenced sources publish a skill with the same name |
SkillToolsResolved | AllToolsResolved | Every skill’s allowed-tools is a tool the pack declares |
If SkillToolsResolved is False, add the tool to the pack’s tools or remove it from the skill’s allowed-tools.
See PromptPack for every skills and skillsConfig field.
Step 3: verify the runtime loads the manifest
Section titled “Step 3: verify the runtime loads the manifest”The operator rebuilds the pod of each AgentRuntime that serves the pack. The runtime container gets:
- Your workspace’s part of the content volume, mounted read-only at
/workspace-content. The pod sees no other workspace’s content. - The env var
OMNIA_PROMPTPACK_MANIFEST_PATH=/workspace-content/manifests/<promptpack-name>.json, where<promptpack-name>is the PromptPack’smetadata.name(support-pack-1-1-0above).
Inspect the pod:
kubectl exec <agent-pod> -n dev-agents -c runtime -- env | grep OMNIA_PROMPTPACKkubectl exec <agent-pod> -n dev-agents -c runtime -- cat /workspace-content/manifests/support-pack-1-1-0.jsonkubectl logs <agent-pod> -n dev-agents -c runtime | grep "skill manifest loaded"The log line lists skillNames, skillMounts, maxActive and selector.
Step 4: test from a session
Section titled “Step 4: test from a session”Open a session and ask about something a skill covers (for ai-safety, handling sensitive content). The runtime gives the model an index of the available skills, and the model calls the skill__activate tool to load the one it needs before answering.
Confirm the activation in the session’s tool calls:
curl -s <session-api-url>/api/v1/sessions/<session-id>/tool-calls \ | jq '.[] | select(.name=="skill__activate")'skill__activate is a server-side tool, so it appears here and in the runtime logs, not as a tool_call message on the WebSocket.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
SkillsResolved=False, reason LookupFailed, message SkillSource ... not found | The SkillSource is not in the PromptPack’s namespace. Lookup does not cross namespaces | kubectl get skillsource -n <pack-ns> |
SkillsResolved=False, reason LookupFailed, message ... has no synced artifact yet | The SkillSource has not finished its first fetch | Wait for status.phase to reach Ready |
SkillsResolved=False, reason ContentStorageUnavailable | The operator started with an empty --workspace-content-path | Set --workspace-content-path on the operator and restart it. The Helm chart always sets it. |
SkillsValid=False, reason NameCollision | Two referenced sources publish skills with the same name | Add include to one of the skills entries |
SkillToolsResolved=False, reason UnknownTool | A SKILL.md allowed-tools entry is not declared in the pack | Declare the tool in the pack or drop it from the skill |
kubectl patch on the PromptPack is rejected | Published versions are immutable | Apply a new version, as in step 2 |
The runtime pod has no workspace-content volume | The pack declares no spec.skills, or the operator has no content storage | Check step 2 and the operator’s --workspace-content-path |