Files
our-claude-skills/custom-skills/31-notion-organizer/code/scripts/_search_llm.py
Andrew Yim 89b20aef16 fix(notion-search): pin SDK model to dated ID + drop unused type alias
Code review caught that the bare alias 'claude-haiku-4-5' works in the
Claude Code CLI but may not resolve in the Anthropic SDK. Pin the
default to 'claude-haiku-4-5-20251001' (the full dated ID) via a
DEFAULT_MODEL constant so the SDK path doesn't silently break the
first time it hits the real API.

Also document the max_tokens-ignored behavior on the CLI path in the
public call_claude docstring (not just the private _call_via_cli),
and drop the unused LLMCaller type alias (dead code).

3/3 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:41:25 +09:00

72 lines
2.0 KiB
Python

"""Claude client abstraction. SDK preferred, `claude -p` CLI fallback."""
from __future__ import annotations
import os
import shutil
import subprocess
# Anthropic SDK requires fully-qualified dated model IDs (the bare alias
# `claude-haiku-4-5` works in Claude Code CLI but may not resolve via SDK).
DEFAULT_MODEL = "claude-haiku-4-5-20251001"
def _have_anthropic_sdk() -> bool:
try:
import anthropic # noqa: F401
return True
except ImportError:
return False
def _have_claude_cli() -> bool:
return shutil.which("claude") is not None
def _call_via_sdk(prompt: str, model: str, max_tokens: int) -> str:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model=model,
max_tokens=max_tokens,
messages=[{"role": "user", "content": prompt}],
)
return response.content[0].text
def _call_via_cli(prompt: str, model: str, max_tokens: int) -> str:
"""Shell out to Claude Code CLI. max_tokens is ignored (CLI handles defaults)."""
result = subprocess.run(
["claude", "-p", prompt, "--model", model],
capture_output=True,
text=True,
check=True,
timeout=60,
)
return result.stdout.strip()
def call_claude(
prompt: str,
*,
model: str = DEFAULT_MODEL,
max_tokens: int = 1000,
) -> str:
"""Send a prompt to Claude.
Tries the anthropic SDK first (requires ANTHROPIC_API_KEY), falls back to
the `claude -p` CLI if available. Raises RuntimeError if neither works.
Note: ``max_tokens`` is honored by the SDK path but ignored by the CLI
path (the CLI sets its own defaults).
"""
if _have_anthropic_sdk() and os.getenv("ANTHROPIC_API_KEY"):
return _call_via_sdk(prompt, model, max_tokens)
if _have_claude_cli():
return _call_via_cli(prompt, model, max_tokens)
raise RuntimeError(
"No Claude client available. Either:\n"
" - Install the `anthropic` SDK and set ANTHROPIC_API_KEY, or\n"
" - Install Claude Code CLI (`claude` on PATH)"
)