src/lm_deluge/skill/SKILL.md
Python library for LLM API requests with unified interface across providers (OpenAI, Anthropic, Google, etc.). Use when writing code that calls LLMs, creates tools/agents, batch processes prompts, or needs rate limiting. Triggers on lm-deluge, lm_deluge, LLMClient, or multi-provider LLM code tasks.
npx skillsauth add taylorai/lm-deluge lm-delugeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Unified async Python client for LLM APIs. Supports OpenAI, Anthropic, Google, Together, Mistral, Groq, and more.
from lm_deluge import LLMClient, Conversation, Tool, APIResponse
llm = LLMClient(model_names="claude-4.5-haiku", max_new_tokens=1024)
response = await llm.start(Conversation().user("Hello!"))
print(response.completion) # Text output - NOT .text
llm = LLMClient(model_names="claude-4.5-haiku", max_new_tokens=1024)
conv = Conversation().user("Search for X and summarize")
final_conv, response = await llm.run_agent_loop(conv, tools=my_tools, max_rounds=5)
Use short names. Full list in src/lm_deluge/models/.
| Short Name | Provider |
|------------|----------|
| claude-4.5-opus, claude-4.5-sonnet, claude-4.5-haiku | Anthropic |
| gpt-4.1-mini, gpt-4-turbo, o1, o3-mini | OpenAI |
| gemini-2.0-flash, gemini-1.5-pro | Google |
OpenAI reasoning models accept suffix: o3-mini-high (sets reasoning effort).
Builder pattern with method chaining:
conv = Conversation()
conv.system("You are helpful")
conv.user("Question here")
conv.ai("Previous response") # For multi-turn
conv.user("Follow-up")
With images/files:
conv.user("Analyze this:", image="path/to/img.png")
conv.user("Summarize:", file="path/to/doc.pdf")
async def search(query: str, limit: int = 10) -> list[dict]:
"""Search the database."""
return results
tool = Tool.from_function(search)
tool = Tool(
name="search",
description="Search database",
parameters={
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "integer", "description": "Max results"},
},
required=["query"],
run=search_function,
)
from pydantic import BaseModel
class SearchParams(BaseModel):
query: str
limit: int = 10
tool = Tool(name="search", parameters=SearchParams, run=search_fn)
| Property | Description |
|----------|-------------|
| .completion | Text response (use this, not .text) |
| .content | Full Message object |
| .is_error | Whether request failed |
| .error_message | Error details if failed |
| .usage | Token usage info |
| .cost | Calculated cost in dollars |
| .thinking | Extended thinking output (if enabled) |
llm = LLMClient(
model_names="claude-4.5-sonnet", # or list for fallback
max_new_tokens=1024,
temperature=0.7,
json_mode=False, # Force JSON output
reasoning_effort="high", # For reasoning models: low/medium/high
thinking_budget=10000, # Token budget for extended thinking
max_requests_per_minute=1000,
max_concurrent_requests=225,
)
prompts = ["Q1", "Q2", Conversation().user("Q3")]
responses = await llm.process_prompts_async(prompts)
# Or sync: llm.process_prompts_sync(prompts)
llm.open(total=100, show_progress=True)
responses = await llm.process_prompts_async(prompts)
llm.close()
task_id = llm.start_nowait(prompt)
# ... do other work ...
response = await llm.wait_for(task_id)
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
response = await llm.start(prompt, output_schema=Person)
response = await llm.start(conv, cache="system_and_tools")
# Options: "tools_only", "system_and_tools", "last_user_message"
Isolated code execution environments:
from lm_deluge.tool.prefab.sandbox import DockerSandbox, JustBashSandbox, SeatbeltSandbox
# Docker (cross-platform)
async with DockerSandbox() as sandbox:
tools = sandbox.get_tools()
conv, resp = await llm.run_agent_loop(conv, tools=tools)
# JustBash (cross-platform, optional dependency: npm install -g just-bash)
async with JustBashSandbox(root_dir=".", working_dir=".") as sandbox:
tools = sandbox.get_tools()
# Seatbelt (macOS only, lighter)
async with SeatbeltSandbox(network_access=False) as sandbox:
tools = sandbox.get_tools()
from lm_deluge import MCPServer
server = MCPServer(name="search", url="https://example.com/mcp")
tools = await server.to_tools() # Convert to Tool objects
# Or pass directly
conv, resp = await llm.run_agent_loop(conv, mcp_servers=[server])
response.completion, never .textrun_agent_loop(), NOT constructorrun_agent_loop_sync() for synctools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.