Skills Compatibility

July 8, 2026 · View on GitHub

Languages: English · 中文

SkillsManager is Agently's internal owner for Skill discovery, progressive context disclosure, capability need discovery, and policy-gated Action candidate binding. It is not a new recommended public API. User code should prefer agent.use_skills(...), AgentExecution Skills selection, and agent.run_skills_task(...) when a compatibility execution facade is needed. Context-pack APIs are advanced custom-planner/TaskDAG integration surfaces, not the ordinary user path. Agently.skills_executor remains for legacy registry, context-pack, resolver, and effort-strategy calls and now delegates to the internal manager.

Agently Skills follow the standard Skills layout: SKILL.md is the capability definition, with optional scripts/, references/, and assets/ resources. Agently does not define a separate Skill authoring manifest.

---
name: release-review
description: Use when checking release readiness and rollback risk.
---

# Release Review

Follow this checklist before recommending a release or rollback...

Declare And Install

For normal Agent runtime, declare Skills on the Agent with use_skills(...). The Skills runtime treats repository/package selectors like Action candidates: it records the source first, performs lightweight SKILL.md discovery during planning, and installs the full Skill only when the planner selects or requires it.

agent.use_skills(
    [{"source": "anthropics/skills", "subpath": "skills/docx"}],
    mode="required",
)

Use install_skills_pack(...) for advanced pool management: prewarming, offline mirrors, deterministic CI fixtures, or explicit registry maintenance. install_skills(...) remains the authoring/smoke-test path for one local Skill directory.

When you author a local Skill, keep it in a real standalone directory that matches the standard layout. Do not build inline SKILL.md strings inside business code and do not use root-level YAML manifests such as skill.yaml. The application should pass the directory path to the compatibility registry facade:

my-skill/
|-- SKILL.md
|-- scripts/
|-- references/
`-- assets/
report = Agently.skills_executor.install_skills_pack(
    "anthropics/skills",
    fetch=True,
    subpath="skills/docx",
    trust_level="remote",
)

Remote installs clone the repository into Agently's local registry source cache, copy standard SKILL.md packages into the registry, and record source URL, ref, resolved commit, subpath, trust level, and checksums. Installing a remote Skill never executes bundled scripts.

install_skills(...) copies a standard local Skill directory into the local registry. The installed Skill root still contains SKILL.md directly. Agently adds its own management files under .agently/ inside the installed copy.

.agently/skills/release-review/
|-- SKILL.md
|-- scripts/
|-- references/
|-- assets/
`-- .agently/
    |-- install.json
    |-- decision_card.json
    |-- resource_index.json
    `-- checksums.json

The .agently/ files speed up routing and inspection. They are not Skill capability definitions. If a derived file is missing or stale, Agently rebuilds or falls back to reading SKILL.md.

skill_id is derived from the SKILL.md frontmatter name: lowercase, whitespace becomes -, and only a-z0-9._- remains. Use the returned contract["skill_id"] when wiring later calls.

contract = Agently.skills_executor.install_skills("./release-review")
agent.use_skills([contract["skill_id"]], mode="model_decision")

Root-level non-standard manifests such as skill.yaml, skill.json, or agently.skill.yaml are rejected. Files with those names inside scripts/, references/, or assets/ are treated as ordinary resources.

Select

Use use_skills(...) to expose installed or remote Skills as route candidates. The model sees concise decision cards first; full guidance and resources are materialized only when the Skills route executes.

agent = Agently.create_agent("ops-assistant")
agent.use_skills(["release-review"], mode="model_decision")
agent.use_skills([{"source": "anthropics/skills", "subpath": "skills/docx"}], mode="required")

Use resolve_skills_plan(...) when you need to inspect which Skills would be used. Required Skills keep the caller-provided order. Multiple optional candidates are ordered by the model.

plan = await agent.async_resolve_skills_plan(
    "Should this release be blocked?",
    skills=["release-review", "incident-triage"],
    mode="model_decision",
)

Execute

Use run_skills_task(...) when the task must be answered through selected Skills. This is a compatibility facade over the Blocks lifecycle: it builds an internal ExecutionPlan with skill_activation PlanBlocks plus a concrete strategy PlanBlock, then lowers that plan to a TriggerFlow-backed ExecutionBlockGraph. The default single_shot route label lowers to a model_request block; multi-step labels such as runtime_chain, staged, and react lower to a trusted flow_segment block. Skills do not declare Agently execution strategies through private frontmatter.

When actions are available, react delegates tool/action planning and execution to the Agent ActionRuntime, so kwargs schemas, MCP tools, policy, approvals, concurrency, and execution-environment handling stay on the Action layer instead of being reimplemented by Skills. Skill activation evidence only proves that guidance and resource context were loaded; side-effect evidence must come from downstream Actions, Workspace operations, waits, or other concrete execution blocks.

execution = await agent.async_run_skills_task(
    "Review this release and give a go/no-go recommendation.",
    skills=["release-review"],
    mode="required",
)

print(execution.status)
print(execution.output)
print(execution.skill_logs)
print(execution.close_snapshot["blocks"]["evidence"])

output= uses the same schema grammar as .output(...); it is the structured-output contract for the Skill run. It describes the business result shape the Skill execution must produce, while output_format= controls whether that result is carried as JSON, flat Markdown, hybrid output, XML-like field envelopes, YAML literal documents, or automatic format selection. The older semantic_outputs= argument is kept only as a deprecated compatibility alias for Skills execution.

execution = await agent.async_run_skills_task(
    "Write a release decision.",
    skills=["release-review"],
    mode="required",
    output={"decision": (str, "go or no-go", True)},
)

Agent prompt methods are also supported for explicit Skills execution. The Skill run consumes the current turn prompt snapshot, uses rendered prompt text as the task, and maps the output / output_format slots to output / output_format:

execution = await (
    agent
    .info({"release": "4.1.2.x"})
    .input("Write a release decision.")
    .output({"decision": (str, "go or no-go", True)}, format="json")
    .async_run_skills_task(skills=["release-review"], mode="required")
)

set_agent_prompt(...) values are inherited and kept for later executions. Quick prompt values are frozen into the Skill run and then cleared from the pending execution prompt. Explicit output= and output_format= arguments override prompt-derived defaults.

output_format= selects how that model response is controlled. Leave it as "auto" for ordinary Skill answers. Auto is structural: it chooses "xml_field" for flat string-only dict schemas, "hybrid" for top-level dicts that combine string fields with typed non-string fields, and "json" for all-control schemas, all-complex schemas, and non-dict outputs. Use explicit "json" for compact all-typed machine-readable results or downstream JSON-only contracts. Use explicit "xml_field" when flat string-only fields benefit from XML-like field boundaries, and explicit "hybrid" for mixed long text plus typed fields. Use explicit "yaml_literal" only when the task intentionally wants a YAML target document.

execution = await agent.async_run_skills_task(
    "Draft a release announcement as HTML.",
    skills=["release-review"],
    mode="required",
    output={"html": (str, "render-ready HTML", True)},
    output_format="xml_field",
)

For fixed required fields, prefer the third tuple element in the schema:

output = {
    "rules": [
        {
            "rule_id": (str, "Stable rule id", True),
            "passed": (bool, "Whether this rule passed", True),
            "evidence": (str, "Concise evidence; empty string is allowed", False),
        }
    ],
    "passes": (bool, "Overall pass/fail", True),
}

Use runtime ensure_keys= only for paths that are conditional or decided at runtime. max_retries=3 means Agently can make up to three additional model attempts when parsing, required keys, strict output validation, or custom validators fail. Retries often recover ordinary omissions, markdown header mistakes, and auto-format degradation to JSON. They can still fail after all attempts when a model repeatedly echoes placeholder scaffolding, returns prose for boolean or numeric fields, produces malformed nested arrays, truncates a large prompt, or must fill many wildcard paths such as rule_results[*].evidence. For model judges with many rules, prefer output_format="json", keep the schema shallow when possible, and split very large rule sets into smaller judge calls.

Direct Skills execution streams runtime items through stream_handler:

  • skills.prompt_only.start
  • skills.model_stream with path, value, delta, and is_complete
  • skills.prompt_only.done
  • skills.runtime_chain.* when effort="normal" or effort="max" selects the built-in planner chain compatibility label
  • skills.staged.* and skills.react.* when those multi-step compatibility labels are selected
  • skills.execution.budget_exhausted when a built-in staged or react strategy stops or truncates work because the configured step budget is exhausted
  • skills.execution.aborted when host cancellation reaches the Skills runtime or when framework execution fails before a normal Skills result can be returned

The Blocks lowering evidence, ExecutionBlockGraph, ResultAdapter output, and TriggerFlow close snapshot are available under execution.close_snapshot["blocks"]. Abort diagnostics include the strategy, effort, elapsed seconds, and the last active runtime event when one is available. Wall-clock and no-progress limits remain host policy; Skills only records the cancellation or failure once it is observed by the runtime.

Annotate direct Skills stream_handler callbacks with SkillRuntimeStreamHandler from agently.types.data. If you are writing a custom Skills effort strategy and call context.async_request_model(..., stream_handler=...), that model-stream handler receives StreamingData and can be annotated with ModelStreamingHandler. Both types are available from the package root: from agently import StreamingData, ModelStreamingHandler.

effort="fast" uses the low-overhead single-shot compatibility label. effort="normal" runs the full preflight -> research -> plan -> execute -> verify -> reflect -> finalize compatibility chain. effort="max" uses the same chain with a larger retry budget and is the planned hook for Dynamic Task escalation. Each label is backed by Blocks plan/evidence metadata in the close snapshot.

Use agent.set_settings("effort_presets", {...}) when you need to override the built-in profile mapping to strategy, model key, step budget, retry count, or artifact inline limit:

agent.set_settings("effort_presets", {
    "fast": {"strategy": "single_shot", "reason_key": "reason_fast", "step_budget": 1},
    "normal": {"strategy": "runtime_chain", "reason_key": "reason", "retry_count": 1},
})

execution = await agent.async_run_skills_task(
    "Draft a release decision.",
    skills=["release-review"],
    mode="required",
    effort="normal",
)

When Skills are selected by Agent auto-orchestration, pass the same effort choice through create_execution(options=...):

from agently.types.options import ExecutionOptions, SkillsRouteOptions

execution = agent.input("Draft a release decision.").create_execution(
    options=ExecutionOptions(
        routes={"skills": SkillsRouteOptions(effort="normal")},
    )
)

For a fully custom action strategy, register an effort strategy handler on the legacy SkillsExecutor facade and invoke it through effort=. This is an advanced compatibility surface; normal applications should use AgentExecution Skills selection and built-in effort presets. The handler receives the Agent runtime context, selected Skills plan, resolved effort config, and output format; it may request models, call Actions/MCP through the context, emit runtime stream items, and return the final output.

The handler follows the SkillsEffortStrategyHandler protocol:

def handler(
    *,
    context: SkillsExecutionContext,
    task: str,
    plan: SkillExecutionPlan,
    output_format: str | None = None,
    effort: str | None = None,
    effort_config: dict | None = None,
) -> Awaitable[Any] | Any: ...

The builtin compatibility route labels are registered through the same strategy table: single_shot, runtime_chain, staged, and react. Use Agently.skills_executor.list_effort_strategies() to inspect the available strategy names. A custom handler may replace a builtin only with replace=True; otherwise duplicate names fail closed. Builtin reference implementations live under agently/builtins/plugins/SkillsExecutor/AgentlySkillsExecutor/modules/effort_strategies/ and are invoked as trusted Blocks runtime handlers, not as a separate Skills-owned lifecycle.

async def audit_plus_strategy(*, context, task, plan, effort_config, **_):
    await context.async_emit_runtime_stream({
        "type": "skills.audit_plus.checkpoint",
        "action": "checkpoint",
    })
    return await context.async_request_model(
        prompt={
            "task": task,
            "selected_skills": plan["selected_skills"],
            "policy": effort_config,
        },
        model_key="verifier",
        output_schema={"decision": (str, "go / no-go", True)},
        output_format="json",
    )

Agently.skills_executor.register_effort_strategy(
    "audit_plus",
    audit_plus_strategy,
)

agent.set_settings("effort_presets", {
    "audit_plus": {"strategy": "audit_plus", "custom_budget": 7},
})

execution = await agent.async_run_skills_task(
    "Audit this release.",
    skills=["release-review"],
    mode="required",
    effort="audit_plus",
)

Skills runtime model calls use symbolic stage keys: planner, research, reason, executor, verifier, reflector, and finalizer. If a key is not mapped in model_pool, Agently leaves the request on the agent's inherited model instead of sending the symbolic key as a provider model name.

When Skills are selected through Agent auto-orchestration, model field stream items are bridged to stable paths like skills.model.fields.<field_path>.

Advanced Context Packs for DAG Consumers

AgentExecution normally asks the internal Skills Manager to build the context pack after the selected Skills are known. Application code should not manage this pack explicitly. When a custom planner, Dynamic Task, or TaskDAG node needs complete Skill context without forcing the whole Skills execution route, it may call the context-pack API as an advanced integration surface. The pack exposes the selected SKILL.md guidance, task-relevant references, examples, optional assets, resource index metadata, citations, diagnostics, and policy-gated action candidates under schema agently.skills.context_pack.v1.

pack = await agent.async_build_skills_context_pack(
    "Generate DeepSeek provider setup code.",
    skills=["model-setup"],
    intent="generate_code",
    include_examples="auto",
    include_references="auto",
    budget_chars=12000,
)

For DAG-shaped execution, reuse the compatibility resolver adapter instead of creating a separate scheduler:

from agently.core import TaskDAGExecutor

snapshot = await TaskDAGExecutor(
    Agently.skills_executor.task_dag_resolver()
).async_run({
    "graph_id": "skill-context-demo",
    "task_schema_version": "task_dag/v1",
    "tasks": [
        {
            "id": "skill_context",
            "kind": "skill",
            "inputs": {
                "task": "Generate provider setup code.",
                "skill_ids": ["model-setup"],
                "intent": "generate_code",
            },
        }
    ],
    "semantic_outputs": {"context": "skill_context"},
})

include_public_lookup=True and actionize_scripts=True remain opt-in host policy operations. Public lookup requires web_search: "allow". Script Actionization requires script_run: "allow" or an approved PolicyApproval decision; it only mounts an allowlisted shell Action candidate and does not run the script.

Bundled scripts and resources are never executed just because a Skill is installed. When a selected standard Skill describes a need for search, browse, HTTP, Workspace file access, Python, shell/script execution, or MCP, Skills Manager records structured capability_needs in the plan. The Skill still does not grant capability. Before execution, Agently compares those needs with host policy and can auto-load only the built-in capabilities explicitly marked allow; approval and off fail closed with diagnostics.

agent.configure_skill_capabilities(
    auto_load={
        "web_search": "allow",
        "web_browse": "allow",
        "workspace_write": "allow",
        "script_run": "approval",
        "shell": "approval",
        "mcp": "approval",
    },
    workspace_root="./.agently/tasks/research",
    search={
        "backend": "auto",
    },
    # Reverse one-time capability mounts after each Skills execution instead of
    # leaving them on the agent. Default "agent" keeps mounts for reuse.
    capability_scope="execution",
    # Only auto-mount capability needs at or above this confidence; lower-
    # confidence needs inferred from SKILL.md prose are advisory. Default: no floor.
    min_auto_mount_confidence=0.8,
    # The built-in HTTP capability default-denies private/loopback/link-local
    # targets; allow specific internal hosts explicitly when needed.
    http_request={"allow_hosts": ["internal.api.example.com"]},
)
agent.configure_policy_approval(handler="input_timeout_fail")

Trusted hosts can enable automatic approval through the framework access-control settings instead of switching the approval handler:

Agently.set_settings("access_control_policy.auto_allow", True)  # process default
agent.set_settings("access_control_policy.auto_allow", True)    # this Agent only

execution = agent.create_execution().access_control_policy({"auto_allow": True})

agent.use_skills(
    [{"source": "owner/skills-with-local-mcp", "auto_allow": True}],
    mode="required",
)

auto_allow=True is host authorization. It can approve Action, ExecutionResource, TaskDAG, Blocks, and Skills capability gates, but it does not remove structural boundaries such as Workspace roots, command allowlists, MCP configuration, HTTP allowlists, or sandbox policy. Selector-level auto_allow=True is scoped to the matching Skill only.

The built-in read-only HTTP capability blocks private, loopback, and link-local hosts by default (an SSRF guard); use http_request={"allow_hosts": [...]} or {"allow_private": true} to allow internal targets. The default script allowlist contains local interpreters (bash, sh, python, node) but not package runners (npx/npm), which fetch and execute arbitrary remote code; add them through policy only when required.

When capability_scope="execution", Agently releases only capabilities that were newly mounted for that execution. If the host Agent already has a matching Action, the internal SkillsManager can reuse that host-owned Action through a fuzzy local Action resolution step, then binds the final execution to the exact action_id. Ambiguous, low-confidence, policy-denied, or unavailable-resource matches fail closed with diagnostics; execution-scoped cleanup must not overwrite or unregister host-owned actions.

For search-oriented Skills, Agently mounts the framework Search package backed by the ddgs Python package. Keep ddgs upgraded in the host environment before real search runs (python -m pip install --upgrade ddgs); Agently does not mutate the host environment at runtime. The backend strategy is not fixed to one provider; use backend="auto" by default, or configure any ddgs-supported backend through host policy. Search treats backend-level "no results" as an empty successful result and falls back through configured/default ddgs backends when a selected backend returns no usable parsed result. If fallback recovers after one or more backend failures, Search reports status="partial_success" with success=True and backend diagnostics so the task can continue while the operator still sees the degraded providers.

Workspace file operations are Workspace-owned. When an Agent has a Workspace, SkillsManager exposes file actions through the Workspace file boundary before falling back to agent.enable_workspace_file_actions(...).

approval is handled by the framework-wide PolicyApproval handler, not by a Skills-local handler. The default is input_timeout_fail: interactive CLI runs ask for input and fail after timeout, while non-interactive services fail immediately. Tests and trusted local fixtures can use auto_approve. Production services should register a handler that matches the service wrapping the TriggerFlow execution, such as a database-backed pending approval record, HTTP callback, webhook resume, SSE/WebSocket wait, or save-and-return interrupt id. Use fail_closed when the host wants a pending diagnostic or a TriggerFlow policy_approval interrupt instead of local input.

SkillsManager does not treat Skill frontmatter such as mcp, mcpServers, allow-scripts, or Agently-specific allowed-actions as capability grants. Public compatibility and metadata may contribute evidence to capability_needs, but loading remains host-policy controlled. Hosts that want model judgment in addition to deterministic Skill reading can enable skills.capability_discovery.model_assisted=True; model-inferred needs are still only evidence and must pass the same host policy gate.

The public Agent Skills allowed-tools field is experimental. If Agently supports it, it can only restrict or pre-approve already-mounted host tools; it does not mount new Actions, create MCP clients, enable shell/file access, or synthesize missing backends.

Acceptance Example

examples/agent_auto_orchestration/19_remote_skills_weather_event_ops.py exercises the 4.1.3 remote-connector path end to end: public remote Skills are declared with agent.use_skills(...), a free weather MCP server is registered through ActionRuntime, the model generates MCP action calls for real weather observations, and the internal SkillsManager lazily materializes the selected Skills before running effort="normal".

Settings

Skill applicability comes from SKILL.md; Agently's .agently/ files are descriptive install metadata only. Multi-step Skills execution composes Agently's existing TriggerFlow, Action, and ExecutionResource boundaries; human approval or durable wait/resume flows should be modeled through TriggerFlow pause_for(...) / continue_with(...) or Action / ExecutionResource approval policies, not by mutating a closed SkillExecution snapshot.

Framework-level skills.* settings may still tune host behavior, such as whether optional Skill candidates disclose full guidance in ordinary prompts. Plugin defaults load first when present; framework settings are the final application-level defaults. Neither setting layer can replace SKILL.md as the Skill capability definition.

Use the legacy SkillsExecutor compatibility helper for local registry options:

Agently.skills_executor.configure(
    registry_root="./.agently/skills-dev",
    allowed_trust_levels=["local"],
)

API Summary

Recommended Agent APIs:

  • agent.use_skills(...)
  • agent.use_skills_packs(...)
  • agent.resolve_skills_plan(...)
  • agent.run_skills_task(...)

Advanced integration API:

  • agent.build_skills_context_pack(...)

Legacy compatibility facade:

  • Agently.skills_executor.install_skills(...)
  • Agently.skills_executor.install_skills_pack(...)
  • Agently.skills_executor.configure(...)
  • Agently.skills_executor.inspect_skills(...)
  • Agently.skills_executor.build_context_pack(...)
  • Agently.skills_executor.task_dag_resolver(...)

SkillContract describes the installed standard Skill, Agently install metadata, decision card, resource index, and checksums. It does not contain framework-authored stage declarations.