LEAP
LEAP builds skills through two pipelines: Branch A distills a skill from raw data, while Branch B combines multiple skills into one. It is called by the main…
Decision protocol for making side-effectful agent tools idempotent — so when an LLM tool call is retried (timeout, framework resume, user re-run, model duplicate emit), the second call is a no-op instead of a double-send. The load-bearing premise: the LM cannot promise it'll
$ npx -y skills add agentsope/SkillAlchemy --skill agentsop-llm-tool-idempotency --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/agentsop-llm-tool-idempotencyContext preview
The summary Claude sees to decide when to auto-load this skill.
Decision protocol for making side-effectful agent tools idempotent — so when an LLM tool call is retried (timeout, framework resume, user re-run, model duplicate emit), the second call is a no-op instead of a double-send. The load-bearing premise: the LM cannot promise it'll
name: agentsop-llm-tool-idempotency
version: 0.1.0
description: >-
Decision protocol for making side-effectful agent tools idempotent — so when an LLM tool
call is retried (timeout, framework resume, user re-run, model duplicate emit), the second
call is a no-op instead of a double-send. The load-bearing premise: the LM cannot promise
it'll call exactly once; the tool must promise the second call is safe. Framework-agnostic
— applies to LangGraph node bodies that re-run on resume, MCP tools, OpenAI tool-calling
retries, CrewAI delegated tool invocations, and direct HTTP wrappers. Search keywords:
duplicate email sent, charged twice, exactly-once, idempotency key, tool called twice,
retry side effect, double-send, at-least-once delivery.
domain: coder-agent / tool-execution-safety
audience: engineers wiring LLM agents whose tools have side effects (email,
payment, DB writes, message posting, file creation, API calls)
trigger_keywords:
- "idempotency key"
- "double send"
- "tool retry"
- "exactly-once"
- "at-least-once"
- "duplicate side effect"
- "node body re-runs on resume"
- "interrupt resumed twice"
when_to_use:
- "any agent tool that performs a side effect: send_email, create_record,
charge_card, post_message, write_file, publish_event, transfer_funds"
- "LangGraph node containing both an interrupt and a side effect"
- "tool that wraps a non-idempotent third-party API (SendGrid, Twilio, S3 PUT
of a generated id)"
- "model-orchestrated workflow where the LM may emit the same tool_call_id
twice due to streaming retries or compaction"
- "MCP server exposing tools to a client that may re-invoke on transport
failure"
when_not_to_use:
- "pure read tools (search, get, list) — already idempotent by HTTP semantics"
- "the side effect is intrinsically commutative (incrementing a counter where
duplicates are acceptable — but verify this; usually they aren't)"
- "single-call manual scripts with no retry layer above"> One-liner: **The LM is at-least-once; the tool must be at-most-once.** > Every framework that promises "durable execution" still re-runs node bodies > on resume. Every HTTP client retries on timeout. Every model occasionally > emits the same tool_call twice. Idempotency belongs in the tool, not in a > wish.
---
Activate this skill when **any** of the following triggers fire:
`post_`, `write_`, `publish_`, `transfer_`, `delete_`, `update_`, or `notify_`.
Discord webhook, S3 PUT, payment gateway, internal write API).
side effect in the same function body — the resume re-runs the body from the top `[langgraph/gotchas]`.
CrewAI delegation, or any layer where a transport timeout could be interpreted as "retry" even though the operation succeeded server-side.
"duplicate row" / "got two emails".
than once within a single user turn.
**Do not activate** when the tool is read-only (GET-equivalent), or when the side effect is genuinely commutative AND verified safe under duplication.
---
LM tool-call semantics Tool side-effect semantics
───────────────────── ─────────────────────────
At-least-once delivery Must be at-most-once
(network retry, framework (one charge, one email,
resume, model dup-emit, one record)
user re-prompt)
│ │
└────── gap to bridge ───────────┘
↓
IDEMPOTENCY KEY
(a stable identifier the LM
commits to BEFORE the call,
which the tool dedupes on)**The LM cannot promise it'll call exactly once.** Four independent retry sources stack here:
1. **Transport retry**: HTTP client (or MCP transport) sees a timeout, the server actually completed the operation, the client retries. Stripe's docs call this out as the canonical case `[stripe/idempotency]`. 2. **Framework resume**: LangGraph re-runs the *entire node body* on resume from an interrupt. Code before the interrupt re-executes on every resume `[langgraph/gotchas]`. Same applies to Temporal-style workflows on replay. 3. **Model duplicate emission**: Streaming sometimes yields the same `tool_call_id` twice (rare but documented in OpenAI tool-calling); model may re-emit on context-compaction round-trips. 4. **User-level retry**: The user clicks "send" twice, or re-runs the agent after timeout, with the same instructions.
Any one of these turns a single-intent action into multiple side effects unless the tool itself dedupes.
Naive design says: "I'll make the LM call the tool exactly once."
Mature design says: "I'll make the tool ignore the second call."
The inversion matters because the LM is in the *control* path; the tool is in the *execution* path. Execution-path guarantees are the only ones that hold under failure.
A common bug: the tool generates a UUID *inside* itself, then dedupes on that UUID. This breaks because retry creates a *new* UUID. The key has to:
key on retry.
up the same key.
Stripe's pattern (the industry reference): client generates an idempot
Turn people, methods, and experience into installable, reusable agent skills. SkillAlchemy is an open-world agent skill creation system that turns underspecified skill briefs and open-world sources into installable, reusable agent skills.
LEAP builds skills through two pipelines: Branch A distills a skill from raw data, while Branch B combines multiple skills into one. It is called by the main…
Lens — Add a cognitive lens to any problem. It accepts a task description and produces an enhanced description that surfaces hidden dimensions, prerequisites,…
Cross-framework enhancement overlay for choosing a multi-agent topology BEFORE writing any agent. A binary-question rubric — is single-agent + tools enough? do…
SOP for terminal-based, git-native AI pair programming with Aider (git work-tree + tree-sitter repo-map + edit-format + human-in-loop REPL). Use when editing…
Screens biomedical / life-science papers for signs of data fabrication, image manipulation, and statistical anomalies, using the detection techniques distilled…
Universal discipline for any LM-driven loop — agent retries, plan-act-observe, multi-agent handoffs, optimiser passes, test-fix cycles. Encodes the one rule…