AGENT SKILL

claudeloop-agent-sdk

Explains how claudeloop integrates with claude-agent-sdk (ClaudeAgentOptions, ClaudeSDKClient vs query(), RateLimitEvent, ResultMessage, AssistantMessage, session discovery via list_sessions()) and the never-block-on-a-human design (permission_mode, can_use_tool, AskUserQuestion handling, hooks). Use this whenever building or modifying src/claudeloop/infrastructure/agent/ (the M2+ agent gateway, options builder, message translation, session catalog, capacity probe), whenever the user asks about the Claude Agent SDK, ClaudeAgentOptions fields, session resumption, rate-limit events, or why a run might block on a human. Make sure to consult this before writing any code that calls claude_agent_sdk directly — infrastructure/agent/ is the ONLY place that import is allowed, per the onion architecture (see the claudeloop-architecture skill), and getting the never-block guarantees wrong here defeats the entire purpose of this project.

License 许可
MIT
最近更新
2026-11-15
Stars
★ 5
Forks
3

01 前言 Front Matter

name
claudeloop-agent-sdk
description
Explains how claudeloop integrates with claude-agent-sdk (ClaudeAgentOptions, ClaudeSDKClient vs query(), RateLimitEvent, ResultMessage, AssistantMessage, session discovery via list_sessions()) and the never-block-on-a-human design (permission_mode, can_use_tool, AskUserQuestion handling, hooks). Use this whenever building or modifying src/claudeloop/infrastructure/agent/ (the M2+ agent gateway, options builder, message translation, session catalog, capacity probe), whenever the user asks about the Claude Agent SDK, ClaudeAgentOptions fields, session resumption, rate-limit events, or why a run might block on a human. Make sure to consult this before writing any code that calls claude_agent_sdk directly — infrastructure/agent/ is the ONLY place that import is allowed, per the onion architecture (see the claudeloop-architecture skill), and getting the never-block guarantees wrong here defeats the entire purpose of this project.

03 SKILL.md 正文

claudeloop + claude-agent-sdk integration

Codex skill mirror of .claude/skills/claudeloop-agent-sdk/SKILL.md. When this guidance changes, update Claude skill, Cursor rule, and .agents/skills/ in the same PR.

infrastructure/agent/ is the only place claude_agent_sdk may be imported — see the claudeloop-architecture skill for the enforced onion rule. This skill covers the SDK integration specifics; consult claudeloop-domain-model for how the resulting signals get classified.

ClaudeSDKClient over query() — this is not optional

query() (single-shot) raises a plain Exception after yielding an error ResultMessage, and the underlying process exits non-zero. A streaming-input ClaudeSDKClient stays alive across error results — you can keep sending messages on one live process with no resume/respawn. The AgentGateway adapter (infrastructure/agent/gateway.py::ClaudeAgentGateway) MUST use ClaudeSDKClient, not query(), or the whole point of collapsing the legacy respawn loop is lost. See ADR 0002 for the full reasoning.

Key ClaudeAgentOptions fields for this project

  • permission_mode="bypassPermissions" — required for autonomy. Note: the Python SDK has no dangerously_skip_permissions field; this is its equivalent. Do not go looking for a field that doesn't exist.
  • can_use_tool — a defensive callback that must NEVER await input. Intercepts AskUserQuestion specifically and denies with guidance (not auto-answers) — see the "Never blocking" section below.
  • output_format — a JSON schema ({complete: bool, remaining_work: [str], blocked_on: str|null, summary: str}) so each turn returns a ResultMessage.structured_output the domain layer's completion.py can evaluate directly, rather than substring-matching output text. Property descriptions (and the autonomy system-prompt fragment) insist blocked_on is only for true external/human blockers — waitable self-started work goes in remaining_work with blocked_on: null, because any non-null value terminates the run as Blocked.
  • resume / continue_conversation / fork_session / session_id — session_id cannot combine with resume/continue_conversation unless fork_session=True is also set. Get this wrong and session resumption breaks in a way that's easy to miss in a quick test. When building options, drop session_id whenever resume or continue_conversation is set (see build_turn_options).
  • setting_sources=None for the throwaway capacity probe specifically — no CLAUDE.md should load for a one-token "are we still limited" check.
  • hooks — PermissionRequest auto-allows; Notification logs only, never blocks.

Never blocking on a human — every mitigation, concretely

Stall path Mitigation
Permission prompts permission_mode="bypassPermissions"
Unexpected permission path Defensive can_use_tool returning PermissionResultAllow without ever awaiting input
AskUserQuestion Intercepted, denied with guidance — e.g. "running autonomously, no user available — choose the option you would recommend, note the assumption, and proceed." NEVER fabricate an answer; that silently invents a decision nobody made.
ExitPlanMode Auto-approved
Notification hooks Logged, never awaited
Model asks "Shall I proceed?" in plain text No tool call to intercept — mitigated via an appended system-prompt fragment establishing autonomous operation
TTY-dependent stdin Never inherit a TTY — must be safe under nohup/systemd
MCP OAuth Genuinely cannot complete unattended — the doctor command checks configured MCP servers up front and fails fast, naming them, rather than discovering the problem mid-run

If you're adding a new tool-interception path, apply the same test every time: can this ever wait on stdin or a human response? If yes, it needs an explicit mitigation in this table before it ships.

Rate-limit signals — read three, trust none alone

RateLimitEvent.rate_limit_info: status (allowed/allowed_warning/ rejected), resets_at, rate_limit_type (five_hour/seven_day/seven_day_opus/seven_day_sonnet/overage), utilization, overage_status, overage_resets_at, overage_disabled_reason. The Claude Code binary contains the string [sdkMessageAdapter] Ignoring rate_limit_event message — treat this event as possibly absent and always corroborate with ResultMessage .api_error_status and AssistantMessage.error (see the claudeloop-domain-model skill's TurnSignals section for exactly how these three combine).

Session discovery — use the supported API

list_sessions() / get_session_info() return SDKSessionInfo (session_id, summary, last_modified, custom_title, first_prompt, git_branch, cwd, tag, created_at) via cheap stat + head/tail reads. Never hand-parse ~/.claude/projects/<encoded-cwd>/*.jsonl directly — the docs explicitly warn the transcript format changes between Claude Code releases, and this API exists specifically to replace that fragile approach from the legacy script.

The capacity probe — deliberately minimal

The throwaway turn used while WAITING (see claudeloop-domain-model): one-token prompt, max_turns=1, no tools, setting_sources=None, and extra_args={"no-session-persistence": None} so it leaves no transcript and doesn't pollute the working session's history with "OK" turns. A rejected probe isn't billed by the API.

Backend profiles — the env overlay reaches the turn AND the probe

A [profiles.<name>] table (--profile / CLAUDELOOP_PROFILE) picks the endpoint Claude Code talks to. The decisions live in domain/backend.py (BackendProfile, BackendRuntime, BackendIdentity); infrastructure/backend.py reads the TOML and the environment; bootstrap.py hands the resolved BackendRuntime to both ClaudeAgentGateway and ClaudeCapacityProbe.

  • The SDK merges options.env over os.environ, so the overlay wins. That is the only way to remove an inherited value: a local profile sets ANTHROPIC_API_KEY="" so a paid key never reaches a local server. Never "just not set" a key you mean to scrub.
  • build_turn_options and build_probe_options both take env= and cli_path=. A probe built without the overlay re-checks capacity on Anthropic while the run talks to Ollama — the defect this fixed.
  • Local (base_url set) implies: every tier named and no claude-* id; Claude Code's haiku/sonnet/opus aliases mapped onto the tiers; --effort not forwarded (pass_effort); --max-budget-usd not forwarded and TurnAccumulator(cost_mode="zero") records $0 — Claude Code prices an unrecognised model at its default model's rate (observed: $0.0008365 for one free qwen2.5-coder:1.5b turn) — while ResultMessage.usage token counts are kept; CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1; web search / deep research refused.
  • Errors a local backend produces (captured from the bundled CLI against Ollama 0.34.2) — AssistantMessage.error / ResultMessage.api_error_status: model not pulled → "model_not_found" / 404; server down → "server_error" / None with "Connection refused … (ConnectionRefused)"; model failed to load → "server_error" / 500; queue full → "server_error" / 503; conversation over context_window → "invalid_request" / None, "Prompt is too long" (Claude Code reserves max_output_tokens out of the window). TurnAccumulator passes local_backend=True into TurnSignals so classify can read them (see claudeloop-domain-model). Claude Code retries a refused connection up to CLAUDE_CODE_MAX_RETRIES times first — about three minutes at the default before claudeloop sees it; extra_env can lower it.
  • A model that writes tool calls as text does nothing — and can fake Done. Observed live: qwen2.5-coder:14b on Ollama answers even a one-tool request with {"name": ..., "arguments": ...} as a text block; inside Claude Code it wrote its Write call and its StructuredOutput call as text, appended the done marker, and the run reported Done for a file it never created. Hence a local profile's done_marker_fallback = false (only a structured verdict completes a run; AutonomousRunner(done_marker_fallback=...) → evaluate(marker_fallback=...)) and doctor's backend-tools check, which POSTs one trivial tool to /v1/messages per tier and wants a tool_use block.
  • AssistantMessageError in the SDK types does not list model_not_found; the CLI sends it anyway. Compare strings, not the Literal.
  • Resume never crosses backends: run meta records backend (anthropic | gateway:<url> | local:<url>) and profile; bootstrap.check_resume_backend refuses a mismatch.

CLAUDE_CODE_RETRY_WATCHDOG — deliberately off by default

Do not set this env var in the default agent gateway configuration. It retries 429/529 in-process indefinitely with no progress reporting, no credits-vs-window discrimination, and no --max-wait. It's exposed as an explicit opt-in flag (--retry-watchdog), never the default. See ADR 0005 for the full reasoning if you're tempted to "simplify" by using it instead of the probe-based waiting policy.

Full reference

docs/architecture/decisions/0002-agent-sdk-over-subprocess.md, docs/architecture/decisions/0005-retry-watchdog-off-by-default.md, docs/architecture/decisions/0007-ask-user-question-denied-with-guidance.md, docs/guides/never-blocking.md, docs/guides/rate-limits-and-credits.md, docs/guides/local-backend.md.

04 同仓库更多 Skills

the-vibey-project
the-vibey-project/vibey

white-paper-writing

Use when writing white papers, technical reports, policy documents, thought leadership pieces, or any long-form authoritative document. Triggers on requests to write, structure, outline, or review white papers, technical reports, position papers, policy briefs, or evidence-driven arguments. Also use for B2B content marketing strategy, technical documentation requiring authority, academic-style reports, or any document that must educate while persuading. Use when someone asks "how should I structure this" for a long-form document.

★ 5
the-vibey-project
the-vibey-project/vibey

prose-technical-mechanics

Use when editing or writing prose at a technical/mechanical level: choosing between Anglo-Saxon and Latinate diction, placing information in topic vs stress positions, writing periodic vs cumulative sentences, handling sentence rhythm, punctuation as logic, transitions, paragraph structure, or phonesthetics. Use when someone wants to understand WHY prose works or doesn't, not just surface-level style advice. Triggers on word choice, sentence structure, emphasis, rhythm, diction, or any deep writing mechanics question.

★ 5
the-vibey-project
the-vibey-project/vibey

prose-mechanics

Use when writing, editing, or analyzing prose style; when trying to avoid generic AI-sounding writing; when applying specific prose styles such as journalistic, academic, narrative, KJV biblical, Hemingway plain, Latinate/Jamesian, Orwellian, Augustan, Victorian, Early Modern (Bacon, Browne, Milton), or free indirect discourse; or when coaching someone on writing voice and mechanics. Triggers on any request to improve, analyze, or write in a specific prose style, to fix "AI-sounding" writing, to make prose more vivid or concrete, to vary sentence rhythm, or to understand how a particular writer achieves their effects.

★ 5
the-vibey-project
the-vibey-project/vibey

narrative-structure

Use when structuring stories, pitches, presentations, white papers, or any persuasive narrative; analyzing the hero's journey in fiction or non-fiction; applying StoryBrand for business communication; designing narrative arcs for thought leadership; or understanding Vogler, Snyder, Propp, or Campbell frameworks. Triggers on any narrative structure, storytelling, pitch structure, StoryBrand, hero's journey, three-act structure, Freytag, Save the Cat, narrative arc, or "how should I structure this story/pitch/presentation" request.

★ 5
the-vibey-project
the-vibey-project/vibey

legal-brief-writing

Use when writing legal briefs, motions, or any court filing; when analyzing judicial cognition and persuasion; when applying elite brief-writing techniques from Roberts, Clement, Kagan, Garner; or when structuring legal arguments for maximum persuasion. Also use for autistic/neurodivergent advocates who need to understand how their natural communication style maps to elite legal advocacy. Triggers on any legal writing, brief drafting, motion preparation, or legal argument structuring request.

★ 5
the-vibey-project
the-vibey-project/vibey

journal-publishability-criteria

Use whenever a research paper, article or preprint is being written, revised, reviewed or published, and specifically before every publication of docs/paper.md. Covers what legitimate journals actually gate on, in order of gating — the editor's desk screen (scope, novelty, package problems), what reviewers judge (methodological soundness, claims the evidence can carry, statistical and qualitative reporting), EQUATOR reporting guidelines, the ICMJE authorship criteria, COPE's view of text recycling, the near-universal generative-AI policy (no AI author, disclosure, author responsibility), TOP 2025 transparency standards, how to verify a journal is legitimate, submitting without an institution, and a pre-submission checklist. Triggers on requests to evaluate, review, prepare or submit a paper, to judge publishability, to write a declarations or data-availability section, to disclose AI use, or to check a journal.

★ 5