opencode-skills-antigravity 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/bundled-skills/ad-creative/SKILL.md +371 -0
  2. package/bundled-skills/ad-creative/evals/evals.json +90 -0
  3. package/bundled-skills/ad-creative/references/generative-tools.md +637 -0
  4. package/bundled-skills/ad-creative/references/platform-specs.md +213 -0
  5. package/bundled-skills/ai-seo/SKILL.md +407 -0
  6. package/bundled-skills/ai-seo/evals/evals.json +90 -0
  7. package/bundled-skills/ai-seo/references/content-patterns.md +285 -0
  8. package/bundled-skills/ai-seo/references/platform-ranking-factors.md +152 -0
  9. package/bundled-skills/backend-dev-guidelines/SKILL.md +1 -1
  10. package/bundled-skills/cc-skill-security-review/SKILL.md +1 -1
  11. package/bundled-skills/churn-prevention/SKILL.md +433 -0
  12. package/bundled-skills/churn-prevention/evals/evals.json +93 -0
  13. package/bundled-skills/churn-prevention/references/cancel-flow-patterns.md +316 -0
  14. package/bundled-skills/churn-prevention/references/dunning-playbook.md +408 -0
  15. package/bundled-skills/claude-api/LICENSE.txt +202 -0
  16. package/bundled-skills/claude-api/SKILL.md +252 -0
  17. package/bundled-skills/claude-api/csharp/claude-api.md +70 -0
  18. package/bundled-skills/claude-api/curl/examples.md +164 -0
  19. package/bundled-skills/claude-api/go/claude-api.md +146 -0
  20. package/bundled-skills/claude-api/java/claude-api.md +128 -0
  21. package/bundled-skills/claude-api/php/claude-api.md +88 -0
  22. package/bundled-skills/claude-api/python/agent-sdk/README.md +269 -0
  23. package/bundled-skills/claude-api/python/agent-sdk/patterns.md +319 -0
  24. package/bundled-skills/claude-api/python/claude-api/README.md +404 -0
  25. package/bundled-skills/claude-api/python/claude-api/batches.md +182 -0
  26. package/bundled-skills/claude-api/python/claude-api/files-api.md +162 -0
  27. package/bundled-skills/claude-api/python/claude-api/streaming.md +162 -0
  28. package/bundled-skills/claude-api/python/claude-api/tool-use.md +587 -0
  29. package/bundled-skills/claude-api/ruby/claude-api.md +87 -0
  30. package/bundled-skills/claude-api/shared/error-codes.md +205 -0
  31. package/bundled-skills/claude-api/shared/live-sources.md +121 -0
  32. package/bundled-skills/claude-api/shared/models.md +68 -0
  33. package/bundled-skills/claude-api/shared/tool-use-concepts.md +305 -0
  34. package/bundled-skills/claude-api/typescript/agent-sdk/README.md +220 -0
  35. package/bundled-skills/claude-api/typescript/agent-sdk/patterns.md +150 -0
  36. package/bundled-skills/claude-api/typescript/claude-api/README.md +313 -0
  37. package/bundled-skills/claude-api/typescript/claude-api/batches.md +106 -0
  38. package/bundled-skills/claude-api/typescript/claude-api/files-api.md +98 -0
  39. package/bundled-skills/claude-api/typescript/claude-api/streaming.md +178 -0
  40. package/bundled-skills/claude-api/typescript/claude-api/tool-use.md +477 -0
  41. package/bundled-skills/codex-review/SKILL.md +1 -1
  42. package/bundled-skills/cold-email/SKILL.md +167 -0
  43. package/bundled-skills/cold-email/evals/evals.json +94 -0
  44. package/bundled-skills/cold-email/references/benchmarks.md +83 -0
  45. package/bundled-skills/cold-email/references/follow-up-sequences.md +81 -0
  46. package/bundled-skills/cold-email/references/frameworks.md +90 -0
  47. package/bundled-skills/cold-email/references/personalization.md +79 -0
  48. package/bundled-skills/cold-email/references/subject-lines.md +53 -0
  49. package/bundled-skills/content-strategy/SKILL.md +374 -0
  50. package/bundled-skills/content-strategy/evals/evals.json +90 -0
  51. package/bundled-skills/content-strategy/references/headless-cms.md +194 -0
  52. package/bundled-skills/context7-auto-research/SKILL.md +1 -1
  53. package/bundled-skills/dbos-golang/SKILL.md +1 -1
  54. package/bundled-skills/dbos-python/SKILL.md +1 -1
  55. package/bundled-skills/dbos-typescript/SKILL.md +1 -1
  56. package/bundled-skills/debug-buttercup/SKILL.md +1 -1
  57. package/bundled-skills/defuddle/SKILL.md +50 -0
  58. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  59. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  60. package/bundled-skills/docs/integrations/jetski-gemini-loader/package.json +1 -0
  61. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  62. package/bundled-skills/docs/maintainers/skills-import-2026-03-21.md +81 -0
  63. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  64. package/bundled-skills/docs/users/bundles.md +1 -1
  65. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  66. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  67. package/bundled-skills/docs/users/getting-started.md +1 -1
  68. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  69. package/bundled-skills/docs/users/usage.md +4 -4
  70. package/bundled-skills/docs/users/visual-guide.md +4 -4
  71. package/bundled-skills/evaluation/SKILL.md +1 -1
  72. package/bundled-skills/exa-search/SKILL.md +1 -1
  73. package/bundled-skills/firecrawl-scraper/SKILL.md +1 -1
  74. package/bundled-skills/frontend-dev-guidelines/SKILL.md +1 -1
  75. package/bundled-skills/gha-security-review/SKILL.md +2 -1
  76. package/bundled-skills/git-pushing/SKILL.md +1 -1
  77. package/bundled-skills/internal-comms/LICENSE.txt +202 -0
  78. package/bundled-skills/internal-comms/SKILL.md +35 -0
  79. package/bundled-skills/internal-comms/examples/3p-updates.md +47 -0
  80. package/bundled-skills/internal-comms/examples/company-newsletter.md +65 -0
  81. package/bundled-skills/internal-comms/examples/faq-answers.md +30 -0
  82. package/bundled-skills/internal-comms/examples/general-comms.md +16 -0
  83. package/bundled-skills/json-canvas/SKILL.md +253 -0
  84. package/bundled-skills/json-canvas/references/EXAMPLES.md +329 -0
  85. package/bundled-skills/lead-magnets/SKILL.md +319 -0
  86. package/bundled-skills/lead-magnets/references/benchmarks.md +129 -0
  87. package/bundled-skills/lead-magnets/references/format-guide.md +196 -0
  88. package/bundled-skills/memory-systems/SKILL.md +1 -1
  89. package/bundled-skills/obsidian-bases/SKILL.md +506 -0
  90. package/bundled-skills/obsidian-bases/references/FUNCTIONS_REFERENCE.md +173 -0
  91. package/bundled-skills/obsidian-cli/SKILL.md +115 -0
  92. package/bundled-skills/obsidian-markdown/SKILL.md +205 -0
  93. package/bundled-skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  94. package/bundled-skills/obsidian-markdown/references/EMBEDS.md +63 -0
  95. package/bundled-skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  96. package/bundled-skills/product-marketing-context/SKILL.md +250 -0
  97. package/bundled-skills/product-marketing-context/evals/evals.json +85 -0
  98. package/bundled-skills/react-best-practices/SKILL.md +1 -1
  99. package/bundled-skills/revops/SKILL.md +352 -0
  100. package/bundled-skills/revops/evals/evals.json +91 -0
  101. package/bundled-skills/revops/references/automation-playbooks.md +290 -0
  102. package/bundled-skills/revops/references/lifecycle-definitions.md +278 -0
  103. package/bundled-skills/revops/references/routing-rules.md +203 -0
  104. package/bundled-skills/revops/references/scoring-models.md +247 -0
  105. package/bundled-skills/sales-enablement/SKILL.md +358 -0
  106. package/bundled-skills/sales-enablement/evals/evals.json +91 -0
  107. package/bundled-skills/sales-enablement/references/deck-frameworks.md +263 -0
  108. package/bundled-skills/sales-enablement/references/demo-scripts.md +355 -0
  109. package/bundled-skills/sales-enablement/references/objection-library.md +270 -0
  110. package/bundled-skills/sales-enablement/references/one-pager-templates.md +208 -0
  111. package/bundled-skills/seo/SKILL.md +139 -0
  112. package/bundled-skills/seo/references/cwv-thresholds.md +108 -0
  113. package/bundled-skills/seo/references/eeat-framework.md +214 -0
  114. package/bundled-skills/seo/references/quality-gates.md +155 -0
  115. package/bundled-skills/seo/references/schema-types.md +118 -0
  116. package/bundled-skills/seo-competitor-pages/SKILL.md +229 -0
  117. package/bundled-skills/seo-content/SKILL.md +186 -0
  118. package/bundled-skills/seo-dataforseo/SKILL.md +395 -0
  119. package/bundled-skills/seo-geo/SKILL.md +254 -0
  120. package/bundled-skills/seo-hreflang/SKILL.md +209 -0
  121. package/bundled-skills/seo-image-gen/SKILL.md +183 -0
  122. package/bundled-skills/seo-images/SKILL.md +193 -0
  123. package/bundled-skills/seo-page/SKILL.md +103 -0
  124. package/bundled-skills/seo-plan/SKILL.md +136 -0
  125. package/bundled-skills/seo-plan/assets/agency.md +175 -0
  126. package/bundled-skills/seo-plan/assets/ecommerce.md +167 -0
  127. package/bundled-skills/seo-plan/assets/generic.md +144 -0
  128. package/bundled-skills/seo-plan/assets/local-service.md +160 -0
  129. package/bundled-skills/seo-plan/assets/publisher.md +153 -0
  130. package/bundled-skills/seo-plan/assets/saas.md +135 -0
  131. package/bundled-skills/seo-programmatic/SKILL.md +184 -0
  132. package/bundled-skills/seo-schema/SKILL.md +178 -0
  133. package/bundled-skills/seo-sitemap/SKILL.md +129 -0
  134. package/bundled-skills/seo-technical/SKILL.md +175 -0
  135. package/bundled-skills/site-architecture/SKILL.md +366 -0
  136. package/bundled-skills/site-architecture/evals/evals.json +88 -0
  137. package/bundled-skills/site-architecture/references/mermaid-templates.md +216 -0
  138. package/bundled-skills/site-architecture/references/navigation-patterns.md +305 -0
  139. package/bundled-skills/site-architecture/references/site-type-templates.md +293 -0
  140. package/bundled-skills/skill-improver/SKILL.md +1 -1
  141. package/bundled-skills/tavily-web/SKILL.md +1 -1
  142. package/bundled-skills/test-fixing/SKILL.md +1 -1
  143. package/bundled-skills/tool-design/SKILL.md +1 -1
  144. package/bundled-skills/ui-ux-pro-max/SKILL.md +1 -1
  145. package/bundled-skills/verification-before-completion/SKILL.md +1 -1
  146. package/bundled-skills/wiki-changelog/SKILL.md +1 -1
  147. package/bundled-skills/wiki-onboarding/SKILL.md +1 -1
  148. package/bundled-skills/wiki-qa/SKILL.md +1 -1
  149. package/bundled-skills/wiki-researcher/SKILL.md +1 -1
  150. package/bundled-skills/wiki-vitepress/SKILL.md +1 -1
  151. package/package.json +1 -1
@@ -0,0 +1,319 @@
1
+ # Agent SDK Patterns — Python
2
+
3
+ ## Basic Agent
4
+
5
+ ```python
6
+ import anyio
7
+ from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
8
+
9
+ async def main():
10
+ async for message in query(
11
+ prompt="Explain what this repository does",
12
+ options=ClaudeAgentOptions(
13
+ cwd="/path/to/project",
14
+ allowed_tools=["Read", "Glob", "Grep"]
15
+ )
16
+ ):
17
+ if isinstance(message, ResultMessage):
18
+ print(message.result)
19
+
20
+ anyio.run(main)
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Custom Tools
26
+
27
+ Custom tools require an MCP server. Use `ClaudeSDKClient` for full control, or pass the server to `query()` via `mcp_servers`.
28
+
29
+ ```python
30
+ import anyio
31
+ from claude_agent_sdk import (
32
+ tool,
33
+ create_sdk_mcp_server,
34
+ ClaudeSDKClient,
35
+ ClaudeAgentOptions,
36
+ AssistantMessage,
37
+ TextBlock,
38
+ )
39
+
40
+ @tool("get_weather", "Get the current weather for a location", {"location": str})
41
+ async def get_weather(args):
42
+ location = args["location"]
43
+ return {"content": [{"type": "text", "text": f"The weather in {location} is sunny and 72°F."}]}
44
+
45
+ server = create_sdk_mcp_server("weather-tools", tools=[get_weather])
46
+
47
+ async def main():
48
+ options = ClaudeAgentOptions(mcp_servers={"weather": server})
49
+ async with ClaudeSDKClient(options=options) as client:
50
+ await client.query("What's the weather in Paris?")
51
+ async for message in client.receive_response():
52
+ if isinstance(message, AssistantMessage):
53
+ for block in message.content:
54
+ if isinstance(block, TextBlock):
55
+ print(block.text)
56
+
57
+ anyio.run(main)
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Hooks
63
+
64
+ ### After Tool Use Hook
65
+
66
+ Log file changes after any edit:
67
+
68
+ ```python
69
+ import anyio
70
+ from datetime import datetime
71
+ from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, ResultMessage
72
+
73
+ async def log_file_change(input_data, tool_use_id, context):
74
+ file_path = input_data.get('tool_input', {}).get('file_path', 'unknown')
75
+ with open('./audit.log', 'a') as f:
76
+ f.write(f"{datetime.now()}: modified {file_path}\n")
77
+ return {}
78
+
79
+ async def main():
80
+ async for message in query(
81
+ prompt="Refactor utils.py to improve readability",
82
+ options=ClaudeAgentOptions(
83
+ allowed_tools=["Read", "Edit", "Write"],
84
+ permission_mode="acceptEdits",
85
+ hooks={
86
+ "PostToolUse": [HookMatcher(matcher="Edit|Write", hooks=[log_file_change])]
87
+ }
88
+ )
89
+ ):
90
+ if isinstance(message, ResultMessage):
91
+ print(message.result)
92
+
93
+ anyio.run(main)
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Subagents
99
+
100
+ ```python
101
+ import anyio
102
+ from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ResultMessage
103
+
104
+ async def main():
105
+ async for message in query(
106
+ prompt="Use the code-reviewer agent to review this codebase",
107
+ options=ClaudeAgentOptions(
108
+ allowed_tools=["Read", "Glob", "Grep", "Agent"],
109
+ agents={
110
+ "code-reviewer": AgentDefinition(
111
+ description="Expert code reviewer for quality and security reviews.",
112
+ prompt="Analyze code quality and suggest improvements.",
113
+ tools=["Read", "Glob", "Grep"]
114
+ )
115
+ }
116
+ )
117
+ ):
118
+ if isinstance(message, ResultMessage):
119
+ print(message.result)
120
+
121
+ anyio.run(main)
122
+ ```
123
+
124
+ ---
125
+
126
+ ## MCP Server Integration
127
+
128
+ ### Browser Automation (Playwright)
129
+
130
+ ```python
131
+ import anyio
132
+ from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
133
+
134
+ async def main():
135
+ async for message in query(
136
+ prompt="Open example.com and describe what you see",
137
+ options=ClaudeAgentOptions(
138
+ mcp_servers={
139
+ "playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}
140
+ }
141
+ )
142
+ ):
143
+ if isinstance(message, ResultMessage):
144
+ print(message.result)
145
+
146
+ anyio.run(main)
147
+ ```
148
+
149
+ ### Database Access (PostgreSQL)
150
+
151
+ ```python
152
+ import os
153
+ import anyio
154
+ from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
155
+
156
+ async def main():
157
+ async for message in query(
158
+ prompt="Show me the top 10 users by order count",
159
+ options=ClaudeAgentOptions(
160
+ mcp_servers={
161
+ "postgres": {
162
+ "command": "npx",
163
+ "args": ["-y", "@modelcontextprotocol/server-postgres"],
164
+ "env": {"DATABASE_URL": os.environ["DATABASE_URL"]}
165
+ }
166
+ }
167
+ )
168
+ ):
169
+ if isinstance(message, ResultMessage):
170
+ print(message.result)
171
+
172
+ anyio.run(main)
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Permission Modes
178
+
179
+ ```python
180
+ import anyio
181
+ from claude_agent_sdk import query, ClaudeAgentOptions
182
+
183
+ async def main():
184
+ # Default: prompt for dangerous operations
185
+ async for message in query(
186
+ prompt="Delete all test files",
187
+ options=ClaudeAgentOptions(
188
+ allowed_tools=["Bash"],
189
+ permission_mode="default" # Will prompt before deleting
190
+ )
191
+ ):
192
+ pass
193
+
194
+ # Plan: agent creates a plan before making changes
195
+ async for message in query(
196
+ prompt="Refactor the auth system",
197
+ options=ClaudeAgentOptions(
198
+ allowed_tools=["Read", "Edit"],
199
+ permission_mode="plan"
200
+ )
201
+ ):
202
+ pass
203
+
204
+ # Accept edits: auto-accept file edits
205
+ async for message in query(
206
+ prompt="Refactor this module",
207
+ options=ClaudeAgentOptions(
208
+ allowed_tools=["Read", "Edit"],
209
+ permission_mode="acceptEdits"
210
+ )
211
+ ):
212
+ pass
213
+
214
+ # Bypass: skip all prompts (use with caution)
215
+ async for message in query(
216
+ prompt="Set up the development environment",
217
+ options=ClaudeAgentOptions(
218
+ allowed_tools=["Bash", "Write"],
219
+ permission_mode="bypassPermissions",
220
+ allow_dangerously_skip_permissions=True
221
+ )
222
+ ):
223
+ pass
224
+
225
+ anyio.run(main)
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Error Recovery
231
+
232
+ ```python
233
+ import anyio
234
+ from claude_agent_sdk import (
235
+ query,
236
+ ClaudeAgentOptions,
237
+ CLINotFoundError,
238
+ CLIConnectionError,
239
+ ProcessError,
240
+ ResultMessage,
241
+ )
242
+
243
+ async def run_with_recovery():
244
+ try:
245
+ async for message in query(
246
+ prompt="Fix the failing tests",
247
+ options=ClaudeAgentOptions(
248
+ allowed_tools=["Read", "Edit", "Bash"],
249
+ max_turns=10
250
+ )
251
+ ):
252
+ if isinstance(message, ResultMessage):
253
+ print(message.result)
254
+ except CLINotFoundError:
255
+ print("Claude Code CLI not found. Install with: pip install claude-agent-sdk")
256
+ except CLIConnectionError as e:
257
+ print(f"Connection error: {e}")
258
+ except ProcessError as e:
259
+ print(f"Process error: {e}")
260
+
261
+ anyio.run(run_with_recovery)
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Session Resumption
267
+
268
+ ```python
269
+ import anyio
270
+ from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage
271
+
272
+ async def main():
273
+ session_id = None
274
+
275
+ # First query: capture the session ID
276
+ async for message in query(
277
+ prompt="Read the authentication module",
278
+ options=ClaudeAgentOptions(allowed_tools=["Read", "Glob"])
279
+ ):
280
+ if isinstance(message, SystemMessage) and message.subtype == "init":
281
+ session_id = message.session_id
282
+
283
+ # Resume with full context from the first query
284
+ async for message in query(
285
+ prompt="Now find all places that call it", # "it" = auth module
286
+ options=ClaudeAgentOptions(resume=session_id)
287
+ ):
288
+ if isinstance(message, ResultMessage):
289
+ print(message.result)
290
+
291
+ anyio.run(main)
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Custom System Prompt
297
+
298
+ ```python
299
+ import anyio
300
+ from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
301
+
302
+ async def main():
303
+ async for message in query(
304
+ prompt="Review this code",
305
+ options=ClaudeAgentOptions(
306
+ allowed_tools=["Read", "Glob", "Grep"],
307
+ system_prompt="""You are a senior code reviewer focused on:
308
+ 1. Security vulnerabilities
309
+ 2. Performance issues
310
+ 3. Code maintainability
311
+
312
+ Always provide specific line numbers and suggestions for improvement."""
313
+ )
314
+ ):
315
+ if isinstance(message, ResultMessage):
316
+ print(message.result)
317
+
318
+ anyio.run(main)
319
+ ```
@@ -0,0 +1,404 @@
1
+ # Claude API — Python
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ pip install anthropic
7
+ ```
8
+
9
+ ## Client Initialization
10
+
11
+ ```python
12
+ import anthropic
13
+
14
+ # Default (uses ANTHROPIC_API_KEY env var)
15
+ client = anthropic.Anthropic()
16
+
17
+ # Explicit API key
18
+ client = anthropic.Anthropic(api_key="your-api-key")
19
+
20
+ # Async client
21
+ async_client = anthropic.AsyncAnthropic()
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Basic Message Request
27
+
28
+ ```python
29
+ response = client.messages.create(
30
+ model="claude-opus-4-6",
31
+ max_tokens=1024,
32
+ messages=[
33
+ {"role": "user", "content": "What is the capital of France?"}
34
+ ]
35
+ )
36
+ print(response.content[0].text)
37
+ ```
38
+
39
+ ---
40
+
41
+ ## System Prompts
42
+
43
+ ```python
44
+ response = client.messages.create(
45
+ model="claude-opus-4-6",
46
+ max_tokens=1024,
47
+ system="You are a helpful coding assistant. Always provide examples in Python.",
48
+ messages=[{"role": "user", "content": "How do I read a JSON file?"}]
49
+ )
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Vision (Images)
55
+
56
+ ### Base64
57
+
58
+ ```python
59
+ import base64
60
+
61
+ with open("image.png", "rb") as f:
62
+ image_data = base64.standard_b64encode(f.read()).decode("utf-8")
63
+
64
+ response = client.messages.create(
65
+ model="claude-opus-4-6",
66
+ max_tokens=1024,
67
+ messages=[{
68
+ "role": "user",
69
+ "content": [
70
+ {
71
+ "type": "image",
72
+ "source": {
73
+ "type": "base64",
74
+ "media_type": "image/png",
75
+ "data": image_data
76
+ }
77
+ },
78
+ {"type": "text", "text": "What's in this image?"}
79
+ ]
80
+ }]
81
+ )
82
+ ```
83
+
84
+ ### URL
85
+
86
+ ```python
87
+ response = client.messages.create(
88
+ model="claude-opus-4-6",
89
+ max_tokens=1024,
90
+ messages=[{
91
+ "role": "user",
92
+ "content": [
93
+ {
94
+ "type": "image",
95
+ "source": {
96
+ "type": "url",
97
+ "url": "https://example.com/image.png"
98
+ }
99
+ },
100
+ {"type": "text", "text": "Describe this image"}
101
+ ]
102
+ }]
103
+ )
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Prompt Caching
109
+
110
+ Cache large context to reduce costs (up to 90% savings).
111
+
112
+ ### Automatic Caching (Recommended)
113
+
114
+ Use top-level `cache_control` to automatically cache the last cacheable block in the request — no need to annotate individual content blocks:
115
+
116
+ ```python
117
+ response = client.messages.create(
118
+ model="claude-opus-4-6",
119
+ max_tokens=1024,
120
+ cache_control={"type": "ephemeral"}, # auto-caches the last cacheable block
121
+ system="You are an expert on this large document...",
122
+ messages=[{"role": "user", "content": "Summarize the key points"}]
123
+ )
124
+ ```
125
+
126
+ ### Manual Cache Control
127
+
128
+ For fine-grained control, add `cache_control` to specific content blocks:
129
+
130
+ ```python
131
+ response = client.messages.create(
132
+ model="claude-opus-4-6",
133
+ max_tokens=1024,
134
+ system=[{
135
+ "type": "text",
136
+ "text": "You are an expert on this large document...",
137
+ "cache_control": {"type": "ephemeral"} # default TTL is 5 minutes
138
+ }],
139
+ messages=[{"role": "user", "content": "Summarize the key points"}]
140
+ )
141
+
142
+ # With explicit TTL (time-to-live)
143
+ response = client.messages.create(
144
+ model="claude-opus-4-6",
145
+ max_tokens=1024,
146
+ system=[{
147
+ "type": "text",
148
+ "text": "You are an expert on this large document...",
149
+ "cache_control": {"type": "ephemeral", "ttl": "1h"} # 1 hour TTL
150
+ }],
151
+ messages=[{"role": "user", "content": "Summarize the key points"}]
152
+ )
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Extended Thinking
158
+
159
+ > **Opus 4.6 and Sonnet 4.6:** Use adaptive thinking. `budget_tokens` is deprecated on both Opus 4.6 and Sonnet 4.6.
160
+ > **Older models:** Use `thinking: {type: "enabled", budget_tokens: N}` (must be < `max_tokens`, min 1024).
161
+
162
+ ```python
163
+ # Opus 4.6: adaptive thinking (recommended)
164
+ response = client.messages.create(
165
+ model="claude-opus-4-6",
166
+ max_tokens=16000,
167
+ thinking={"type": "adaptive"},
168
+ output_config={"effort": "high"}, # low | medium | high | max
169
+ messages=[{"role": "user", "content": "Solve this step by step..."}]
170
+ )
171
+
172
+ # Access thinking and response
173
+ for block in response.content:
174
+ if block.type == "thinking":
175
+ print(f"Thinking: {block.thinking}")
176
+ elif block.type == "text":
177
+ print(f"Response: {block.text}")
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Error Handling
183
+
184
+ ```python
185
+ import anthropic
186
+
187
+ try:
188
+ response = client.messages.create(...)
189
+ except anthropic.BadRequestError as e:
190
+ print(f"Bad request: {e.message}")
191
+ except anthropic.AuthenticationError:
192
+ print("Invalid API key")
193
+ except anthropic.PermissionDeniedError:
194
+ print("API key lacks required permissions")
195
+ except anthropic.NotFoundError:
196
+ print("Invalid model or endpoint")
197
+ except anthropic.RateLimitError as e:
198
+ retry_after = int(e.response.headers.get("retry-after", "60"))
199
+ print(f"Rate limited. Retry after {retry_after}s.")
200
+ except anthropic.APIStatusError as e:
201
+ if e.status_code >= 500:
202
+ print(f"Server error ({e.status_code}). Retry later.")
203
+ else:
204
+ print(f"API error: {e.message}")
205
+ except anthropic.APIConnectionError:
206
+ print("Network error. Check internet connection.")
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Multi-Turn Conversations
212
+
213
+ The API is stateless — send the full conversation history each time.
214
+
215
+ ```python
216
+ class ConversationManager:
217
+ """Manage multi-turn conversations with the Claude API."""
218
+
219
+ def __init__(self, client: anthropic.Anthropic, model: str, system: str = None):
220
+ self.client = client
221
+ self.model = model
222
+ self.system = system
223
+ self.messages = []
224
+
225
+ def send(self, user_message: str, **kwargs) -> str:
226
+ """Send a message and get a response."""
227
+ self.messages.append({"role": "user", "content": user_message})
228
+
229
+ response = self.client.messages.create(
230
+ model=self.model,
231
+ max_tokens=kwargs.get("max_tokens", 1024),
232
+ system=self.system,
233
+ messages=self.messages,
234
+ **kwargs
235
+ )
236
+
237
+ assistant_message = response.content[0].text
238
+ self.messages.append({"role": "assistant", "content": assistant_message})
239
+
240
+ return assistant_message
241
+
242
+ # Usage
243
+ conversation = ConversationManager(
244
+ client=anthropic.Anthropic(),
245
+ model="claude-opus-4-6",
246
+ system="You are a helpful assistant."
247
+ )
248
+
249
+ response1 = conversation.send("My name is Alice.")
250
+ response2 = conversation.send("What's my name?") # Claude remembers "Alice"
251
+ ```
252
+
253
+ **Rules:**
254
+
255
+ - Messages must alternate between `user` and `assistant`
256
+ - First message must be `user`
257
+
258
+ ---
259
+
260
+ ### Compaction (long conversations)
261
+
262
+ > **Beta, Opus 4.6 only.** When conversations approach the 200K context window, compaction automatically summarizes earlier context server-side. The API returns a `compaction` block; you must pass it back on subsequent requests — append `response.content`, not just the text.
263
+
264
+ ```python
265
+ import anthropic
266
+
267
+ client = anthropic.Anthropic()
268
+ messages = []
269
+
270
+ def chat(user_message: str) -> str:
271
+ messages.append({"role": "user", "content": user_message})
272
+
273
+ response = client.beta.messages.create(
274
+ betas=["compact-2026-01-12"],
275
+ model="claude-opus-4-6",
276
+ max_tokens=4096,
277
+ messages=messages,
278
+ context_management={
279
+ "edits": [{"type": "compact_20260112"}]
280
+ }
281
+ )
282
+
283
+ # Append full content — compaction blocks must be preserved
284
+ messages.append({"role": "assistant", "content": response.content})
285
+
286
+ return next(block.text for block in response.content if block.type == "text")
287
+
288
+ # Compaction triggers automatically when context grows large
289
+ print(chat("Help me build a Python web scraper"))
290
+ print(chat("Add support for JavaScript-rendered pages"))
291
+ print(chat("Now add rate limiting and error handling"))
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Stop Reasons
297
+
298
+ The `stop_reason` field in the response indicates why the model stopped generating:
299
+
300
+ | Value | Meaning |
301
+ |-------|---------|
302
+ | `end_turn` | Claude finished its response naturally |
303
+ | `max_tokens` | Hit the `max_tokens` limit — increase it or use streaming |
304
+ | `stop_sequence` | Hit a custom stop sequence |
305
+ | `tool_use` | Claude wants to call a tool — execute it and continue |
306
+ | `pause_turn` | Model paused and can be resumed (agentic flows) |
307
+ | `refusal` | Claude refused for safety reasons — output may not match your schema |
308
+
309
+ ---
310
+
311
+ ## Cost Optimization Strategies
312
+
313
+ ### 1. Use Prompt Caching for Repeated Context
314
+
315
+ ```python
316
+ # Automatic caching (simplest — caches the last cacheable block)
317
+ response = client.messages.create(
318
+ model="claude-opus-4-6",
319
+ max_tokens=1024,
320
+ cache_control={"type": "ephemeral"},
321
+ system=large_document_text, # e.g., 50KB of context
322
+ messages=[{"role": "user", "content": "Summarize the key points"}]
323
+ )
324
+
325
+ # First request: full cost
326
+ # Subsequent requests: ~90% cheaper for cached portion
327
+ ```
328
+
329
+ ### 2. Choose the Right Model
330
+
331
+ ```python
332
+ # Default to Opus for most tasks
333
+ response = client.messages.create(
334
+ model="claude-opus-4-6", # $5.00/$25.00 per 1M tokens
335
+ max_tokens=1024,
336
+ messages=[{"role": "user", "content": "Explain quantum computing"}]
337
+ )
338
+
339
+ # Use Sonnet for high-volume production workloads
340
+ standard_response = client.messages.create(
341
+ model="claude-sonnet-4-6", # $3.00/$15.00 per 1M tokens
342
+ max_tokens=1024,
343
+ messages=[{"role": "user", "content": "Summarize this document"}]
344
+ )
345
+
346
+ # Use Haiku only for simple, speed-critical tasks
347
+ simple_response = client.messages.create(
348
+ model="claude-haiku-4-5", # $1.00/$5.00 per 1M tokens
349
+ max_tokens=256,
350
+ messages=[{"role": "user", "content": "Classify this as positive or negative"}]
351
+ )
352
+ ```
353
+
354
+ ### 3. Use Token Counting Before Requests
355
+
356
+ ```python
357
+ count_response = client.messages.count_tokens(
358
+ model="claude-opus-4-6",
359
+ messages=messages,
360
+ system=system
361
+ )
362
+
363
+ estimated_input_cost = count_response.input_tokens * 0.000005 # $5/1M tokens
364
+ print(f"Estimated input cost: ${estimated_input_cost:.4f}")
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Retry with Exponential Backoff
370
+
371
+ > **Note:** The Anthropic SDK automatically retries rate limit (429) and server errors (5xx) with exponential backoff. You can configure this with `max_retries` (default: 2). Only implement custom retry logic if you need behavior beyond what the SDK provides.
372
+
373
+ ```python
374
+ import time
375
+ import random
376
+ import anthropic
377
+
378
+ def call_with_retry(
379
+ client: anthropic.Anthropic,
380
+ max_retries: int = 5,
381
+ base_delay: float = 1.0,
382
+ max_delay: float = 60.0,
383
+ **kwargs
384
+ ):
385
+ """Call the API with exponential backoff retry."""
386
+ last_exception = None
387
+
388
+ for attempt in range(max_retries):
389
+ try:
390
+ return client.messages.create(**kwargs)
391
+ except anthropic.RateLimitError as e:
392
+ last_exception = e
393
+ except anthropic.APIStatusError as e:
394
+ if e.status_code >= 500:
395
+ last_exception = e
396
+ else:
397
+ raise # Client errors (4xx except 429) should not be retried
398
+
399
+ delay = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay)
400
+ print(f"Retry {attempt + 1}/{max_retries} after {delay:.1f}s")
401
+ time.sleep(delay)
402
+
403
+ raise last_exception
404
+ ```