Skip to content

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.

  • 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 kubectl that can reach the workspace namespace (dev-agents below).

Save as skills.yaml. The repository URL, tag and skill names are illustrative; use your own.

apiVersion: omnia.altairalabs.ai/v1alpha1
kind: SkillSource
metadata:
name: support-skills
namespace: dev-agents
spec:
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:

Terminal window
kubectl apply -f skills.yaml
kubectl get skillsource support-skills -n dev-agents -w

The source is synced when PHASE is Ready and SKILLS matches the filtered set. Then check that every retained SKILL.md parsed:

Terminal window
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.

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/v1alpha1
kind: PromptPack
metadata:
name: support-pack-1-1-0
namespace: dev-agents
spec:
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: 5

To 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.

Terminal window
kubectl apply -f pack-v2.yaml

An 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:

Terminal window
kubectl get promptpack support-pack-1-1-0 -n dev-agents \
-o jsonpath='{range .status.conditions[*]}{.type} {.status} {.reason}{"\n"}{end}'
ConditionReason when TrueMeaning
SkillsResolvedAllSkillsResolvedEvery spec.skills[].source exists and has synced
SkillsValidNoCollisionsNo two referenced sources publish a skill with the same name
SkillToolsResolvedAllToolsResolvedEvery 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’s metadata.name (support-pack-1-1-0 above).

Inspect the pod:

Terminal window
kubectl exec <agent-pod> -n dev-agents -c runtime -- env | grep OMNIA_PROMPTPACK
kubectl exec <agent-pod> -n dev-agents -c runtime -- cat /workspace-content/manifests/support-pack-1-1-0.json
kubectl logs <agent-pod> -n dev-agents -c runtime | grep "skill manifest loaded"

The log line lists skillNames, skillMounts, maxActive and selector.

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:

Terminal window
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.

SymptomLikely causeFix
SkillsResolved=False, reason LookupFailed, message SkillSource ... not foundThe SkillSource is not in the PromptPack’s namespace. Lookup does not cross namespaceskubectl get skillsource -n <pack-ns>
SkillsResolved=False, reason LookupFailed, message ... has no synced artifact yetThe SkillSource has not finished its first fetchWait for status.phase to reach Ready
SkillsResolved=False, reason ContentStorageUnavailableThe operator started with an empty --workspace-content-pathSet --workspace-content-path on the operator and restart it. The Helm chart always sets it.
SkillsValid=False, reason NameCollisionTwo referenced sources publish skills with the same nameAdd include to one of the skills entries
SkillToolsResolved=False, reason UnknownToolA SKILL.md allowed-tools entry is not declared in the packDeclare the tool in the pack or drop it from the skill
kubectl patch on the PromptPack is rejectedPublished versions are immutableApply a new version, as in step 2
The runtime pod has no workspace-content volumeThe pack declares no spec.skills, or the operator has no content storageCheck step 2 and the operator’s --workspace-content-path