AgentStack
SKILL verified Apache-2.0 Self-run

Tools

skill-skillberry-ai-cap-evolve-tools · by skillberry-ai

Optimize an agent's OWN tool surface (tools it implements, not an external MCP server). Use when the agent mis-selects tools, fills arguments wrong, or has a confusing/redundant toolset. You may edit tool names, descriptions, parameter docs, in-description examples, the JSON schema/API, the tool code itself, ADD tools (including composite tools that call existing tools), and REMOVE tools — all un…

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-skillberry-ai-cap-evolve-tools

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Tools? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Capability: tools (full control)

This capability treats the agent's entire tool surface as the optimizable artifact. When an agent owns its tools — it implements the handlers, defines the wire schema, and controls every caller — then names, descriptions, parameter docs, in-description examples, the JSON Schema, and the implementation code are all fair game.

Use this capability when the agent OWNS its tools — it implements the handlers and controls the wire schema, so the code itself is editable. (When the tools come from an external server you can only re-describe, not re-implement, the action policy here is tightened to documentation-only edits.)

What you can change here

The tool's docstring AND its return value are what the agent SEES — make both clear and recovery-oriented. The doc surface (description, important-notes, per-param, Raises:, examples) drives which tool the model calls and how it fills the arguments; the return value (and especially the error text) steers the next turn. Each lever below is an edit class; in ONE pass, apply EVERY edit class the traces call for — a validation wrapper AND a loop tool AND enriched returns/errors AND doc fixes across all implicated tools can and should all ship in the same candidate. (1-line generic examples; worked bodies in [references/examples.md](references/examples.md), depth below and in [references/concepts.md](references/concepts.md).)

Read this skill in full before editing. Ship MULTIPLE fixes per iteration — but every one must be REAL (targets a currently-failing task), SAFE (cannot change a passing task's behavior), and VERIFIED (proven to fix its target). Several such fixes beat a long list that includes a speculative edit: one edit that regresses a passing task can sink the whole candidate at the gate. Quality over churn — never add an edit to hit a count, and never re-add a rule/tool the run already tried and rejected.

Per-change SAFETY (the rule that makes multi-change work). Scope every guard to fire ONLY on the exact violating condition, and check its blast radius: run it on the args of 1–2 currently-PASSING tasks that use the same tool and confirm it does NOT fire. A guard that fires on a passing task is a regression — rescope or drop it. This is how you ship many changes without net-zero churn.

Pick the lever by failure type — the in-body guard is the DEFAULT strong move:

  • Edit the BODY of an EXISTING tool (reach for this FIRST for a rule violation). When

the agent VIOLATES a rule a tool already owns (a wrong field value, an id not on file, an action on a record whose state forbids it), convert the prose rule into a scoped in-body guard. This is the highest-yield, lowest-regression edit; expect to touch SEVERAL existing bodies in one iteration.

  • ADD a NEW code-bearing tool — for a genuine CAPABILITY GAP or action STALL. A

composite atomic-WRITE tool for a multi-step action the agent narrates/confirms then fails to execute is the canonical case (the primitive is what it skips; the composite makes the action un-skippable; then REMOVE the raw primitives). New tools are available and encouraged WHEN they close a real gap — but add one ONLY if the agent will actually call it AND it changes the graded outcome. Do NOT add read/compute/summary helper tools that a guard or a prompt line would subsume, and never add a tool just to "ship a new tool" — that is churn the gate punishes.

  • **DECISION / PERMISSION cluster → a discriminating-predicate guard (the BOUNDED-blast-

radius alternative to a prompt change).** When a cluster is about ACT-vs-REFUSE (the agent acted where it should have refused/escalated, or vice versa), the WRONG fix is loosening a global decision rule in the prompt — that has UNBOUNDED blast radius and regresses every task where the original behavior was gold. The RIGHT fix lives here: an in-body guard on the tool that owns the action, expressing the EXACT policy predicate, that refuses/raises ONLY when the qualifying condition is/isn't met. It fires only on the narrow violating condition, so its blast radius is bounded to the failing inputs — the SAFEST edit, preferred over any prompt/permission change.

  • HARD-ZERO / capability-gap cluster → a REAL targeted tool, never prose. A task

scoring 0.00 that needs a compute / composite / discriminating-predicate tool stays 0.00 after any docstring or prompt reword. Ship a tool the agent will CALL that changes the graded state.

The two failure modes to avoid: (1) leaving a rule the agent keeps breaking as loose prose instead of a guard, or loosening a global permission rule (unbounded regression) instead of a scoped guard; (2) padding the candidate with low-value helper tools or cosmetic rewrites that move no graded task.

  1. **Edit the CODE of EXISTING tools to enforce rules deterministically (the most

common high-leverage edit)** — most violated textual rules govern a tool that ALREADY exists, and the fix is an in-body guard there, not a new tool. Bake the precondition / normalization / actionable refusal into the body so correctness doesn't depend on the LLM. Ex: add if not rec["cancellable"]: raise ValueError("not cancellable; reason=...; do X instead") to the existing cancel_record body. Expect to touch the BODIES of SEVERAL existing tools per iteration — one per violated rule.

  1. Add a new tool (first-class — reach for it freely) — give the agent a

capability it lacks or a safe path it keeps skipping, built as a thoughtful workflow/validation tool, not a thin wrapper. Ex: search_logs returns only the relevant lines instead of a raw dump; or a find_duplicate_records the agent has no way to compute today. For a STALL or capability-gap cluster this is the right move even when a primitive exists — see item 7 (composite atomic-WRITE).

  1. Replace / wrap a tool — superset an existing tool and route the old behavior

through it. Ex: wrap find_record+charge_payment behind one charge_record(record_id) that resolves then charges.

  1. Improve a tool's documentation — sharpen description / important-notes /

Raises: / per-param docs / examples; rename for least surprise. Ex: lookup(record)get_record(record_id: str) with "returns an error object if not found."

  1. Improve RETURN VALUES for recoverability — high-signal fields, stable

human-readable ids, and actionable error text with a next-step hint and what NOT to do. Ex: error returns "payment method not on file; available: ['card_1'] — pass one of these" instead of a raw traceback.

  1. Add a loop tool — replace N repeated single-item calls with one list call.

Ex: get_records(ids: [...]) replaces N× get_record(id).

  1. **Add a composite atomic-WRITE / workflow tool (first-class — the fix for STALLS

and multi-step writes)** — for a recurring, failure-prone multi-step action (especially one the agent narrates/confirms then fails to execute, e.g. a multi-step update that must cancel/undo then re-create a record), a deterministic tool whose body performs ALL the steps in order via the existing primitives, then remove the raw primitives so the action is un-skippable. Ex: apply_change_plan(record_id, steps) validates → applies each → returns final state as one reliable call. Reach for this whenever a cluster STALLS at the action boundary — do not settle for a prose "be sure to act" rule.

  1. Remove-with-replacement — remove a redundant/overlapping tool only after a

replacement preserving its capability exists. Ex: drop query once get_record + search_records cover it.

Before/after — convert a violated prose rule into an in-body guard (the default edit). The rule "a record can only be cancelled when it is cancellable" lives as prose in the prompt and the agent keeps breaking it. Don't add a tool — edit the EXISTING cancel_record body:

  def cancel_record(record_id):
+     rec = get_record(record_id)
+     if not rec["cancellable"]:
+         raise ValueError(
+             "not cancellable; reason=" + rec.get("status", "unknown")
+             + "; do X instead (e.g. offer a change_record)")
      return _backend.cancel(record_id)

And the rule "amounts are in whole cents and the method must be on file" — edit the EXISTING book (or charge) body to normalize the field then raise an actionable error:

  def book(record_id, amount, payment_id):
+     amount = int(round(amount))            # normalize: callers pass dollars
+     methods = {m["id"] for m in get_record(record_id)["payment_methods"]}
+     if payment_id not in methods:
+         raise ValueError(
+             f"payment method {payment_id!r} not on file; "
+             f"available={sorted(methods)} — pass one of these")
      return _backend.book(record_id, amount, payment_id)

Both fixes touch a tool that ALREADY exists; no new tool is needed. A docstring-only or new-tool-only iteration that leaves these rules as prose is under-used.

Guardrails (depth below): encode deterministic logic in code, not prose (a tool body the model cannot skip beats a sentence it can forget); keep the toolset small and namespaced (aim **": raise ...` — that overfits to one task, gets rejected by the held-out gate, and helps nothing else. Use a failing task's specifics only to identify the class, then write the general check.

A discriminating-predicate guard for a decision/permission cluster must encode the GENERAL policy condition that separates the qualifying cases from the rest (e.g. if record.tier == "restricted" and action == "modify": raise ...), NOT a global behavior flip and NOT a task literal. The guard NARROWS — it fires only on the cases the policy actually governs — so passing tasks outside that condition keep their behavior unchanged.

The highest-leverage edit: deterministic CODE (usually in an EXISTING tool body)

Start here. A deterministic guard in code beats a sentence in the prompt. A docstring or system-prompt rule only makes the model more likely to comply — it can be forgotten, mis-read, or out-reasoned on the next task. Code (a precondition check, a normalization, a loop) makes the right behavior the only thing that can happen — it cannot be "forgotten." When the traces show a rule the agent keeps breaking, a multi-step action it keeps fumbling, or — most importantly — an action it stalls on and never executes, do not just reword a description — put the behavior in code.

Two code-bearing edits, chosen by failure type — both first-class. For a rule VIOLATION, enforce the rule in the body of the EXISTING tool that owns it — "only cancel a cancellable record" governs cancel_record, "amounts in whole cents" governs book/charge; add an in-body guard there and expect to touch SEVERAL existing bodies per iteration. For a CAPABILITY GAP or an action STALL, write a NEW code-bearing tool — a loop tool to collapse a multi-call chain, or (the big one) a composite atomic-WRITE tool to encapsulate a multi-step write the agent keeps skipping. Do not treat the new tool as a last resort: when a cluster stalls at the action boundary, the composite is the correct fix even though a write primitive already exists, because the primitive is exactly what the agent declines to call. (See the before/after diffs above, the three patterns below, and the worked bodies in [references/examples.md](references/examples.md).)

Prose cannot fix a BEHAVIORAL failure. There is a sharp distinction the optimizer must make. If the agent does not know something (a format, a rule, a decision criterion), prose can teach it — that is a KNOWLEDGE gap, and it belongs in the prompt. But if the agent demonstrably knows what to do and still doesn't do it — it analyzes the situation, explains the plan, even gets the user's confirmation, and then simply fails to CALL the action tool and stops — that is a BEHAVIORAL failure, and more prose does not fix it. You cannot instruct a model out of a behavior it already "agreed" to and then skipped. The only reliable fix is to move the behavior into CODE: encapsulate the whole action in a tool whose body performs it, so executing it is no longer a choice the model can decline mid-conversation. Telling the agent to "be sure to act" is exactly the kind of edit the traces show failing.

Three patterns carry almost all the gain (worked bodies below and in [references/examples.md](references/examples.md)):

  1. Validation / rule-enforcement tool (wrap, then delegate). When a rule or

precondition that today lives only in the prompt is GENERAL — it always applies, not just to one task — implement it as code in a NEW tool that: validates / normalizes the inputs → enforces the rule → calls the existing primitive → returns a clear result (or a clean refusal). Then remove the raw primitive from the exposed set if the agent should only ever reach it through the safe path. Example: cancel_record_safely(record_id) reads the record, refuses unless it is cancellable, then calls the raw cancel_record.

  1. Workflow / loop tool (collapse a recurring multi-step sequence). When a

small multi-step workflow recurs, or the agent calls one primitive N times in a row (and drops or mis-threads a result), implement it as ONE tool with real loops/code that calls the existing tools internally and returns the finished result. Example: a tool that loops over a list of ids calling get_record once each and returns them aligned, instead of the agent issuing N calls.

  1. **Write / workflow COMPOSITE tool — make a stalled action un-skippable

(co-equal PRIMARY pattern). This is the fix for the single most common BEHAVIORAL failure: the agent reliably stalls at the action/write boundary** — it analyzes, explains, even confirms with the user, then never issues the write call and stops, leaving the task half-done. The cure is not a stronger rule. Encapsulate the ENTIRE multi-step action (analyze → confirm → act) as ONE composite tool whose body performs all the steps in code — calling the existing primitives in the right sequence and looping where needed — so the action completes the moment the tool is called and cannot be skipped mid-conversation. Then remove the raw primitives so the composite is the only path; the safe, complete behavior is then the only behavior reachable. Generic example: an apply_change_plan(record_id, steps) that performs a multi-step update atomically — validating each step, applying them in order via the existing write primitives, and returning the final state — so the agent hands over the plan in one call instead of narrating it and then failing to execute. (Worked body in [references/examples.md](references/examples.md) §3e.)

Lean caveat — replace, don't accumulate. Every exposed tool enters the agent's context, and too many tools degrade selection (see §3 of concepts.md). So PREFER consolidating over piling on: when you add a safer or looped tool, remove the now-redundant primitive so the net tool count stays small and sharp. Do not add many narrow tools. One sharp tool that subsumes a primitive beats two overlapping ones.

SAFE TOOL-REPLACEMENT PROTOCOL (never bare-remove a tool). To replace or consolidate a tool, follow these steps in order — never delete a tool without a replacement that subsumes it:

  1. ADD a wrapper tool whose body CALLS the existing tool — after validation,

normalization, or the extra steps you want guaranteed. The wrapper delegates to the primitive; it does not re-implement it.

  1. VERIFY the wrapper (run validate; confirm the body actually calls the

primitive and returns a sane result).

  1. Only then SWAP the registration: remove the raw primitive from

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.