Skip to main content

High-performance debounce library for Python with async support and LLM framework integrations

Project description

Quieto

High-performance async debounce library for Python 3.13+ with message coalescing, designed for LLM-powered applications.

Built with Claude Code — this entire codebase (architecture, implementation, tests, and this README) was written by Claude 4.6 Opus via Claude Code.

The problem

When users interact with LLM-powered apps, they often send messages in quick succession:

t=0.0s  User: "hi"
t=2.0s  User: "everything ok?"

Without debouncing, this triggers 2 separate LLM API calls. With debouncing, both messages are coalesced into 1 call:

LLM receives: ["hi", "everything ok?"]

Install

uv add quieto

With LangChain integration:

uv add quieto[langchain]

Or with pip:

pip install quieto

Quick start

Decorator API

from quieto import debounce

@debounce(delay=2.0, max_wait=10.0)
async def handle(messages: list[str]) -> str:
    return await llm.invoke("\n".join(messages))

# Each call pushes a message; the function fires after 2s of quiet
await handle("hi")
await handle("everything ok?")
# -> handle is called once with ["hi", "everything ok?"]

Imperative API

from quieto import quieto, DebounceConfig

async with quieto(config=DebounceConfig(delay=2.0, max_wait=10.0)) as d:
    await d.push("hello")
    await d.push("world")
    batch = await d.next_batch()  # ["hello", "world"]

Async iterator

async for batch in quieto.batches():
    response = await llm.invoke(batch)

Strategies

Strategy Enum Description
Trailing Strategy.TRAILING Default. Resets timer on each message, max_wait caps total buffering time.
Adaptive Strategy.ADAPTIVE Learns from user behavior via EMA. Fast typists get shorter delays.
Actor Strategy.ACTOR Queue-based with natural backpressure via asyncio.Queue.
from quieto import quieto, DebounceConfig, Strategy

d = quieto(config=DebounceConfig(
    delay=2.0,
    max_wait=10.0,
    strategy=Strategy.ADAPTIVE,
))

Session manager

Independent debounce state per user/session:

from quieto import SessionManager

async with SessionManager(delay=2.0, max_wait=10.0) as mgr:
    await mgr.push("session-123", "hi")
    await mgr.push("session-123", "everything ok?")
    await mgr.push("session-456", "different user")

    batch_123 = await mgr.next_batch("session-123")  # ["hi", "everything ok?"]
    batch_456 = await mgr.next_batch("session-456")  # ["different user"]

Idle sessions are garbage-collected automatically.

LangChain middleware

from langchain.agents import create_agent
from quieto.integrations.langchain import DebounceMiddleware

agent = create_agent(
    model="gpt-4.1",
    tools=[...],
    middleware=[DebounceMiddleware(delay=2.0, max_wait=10.0)],
)

The middleware implements wrap_model_call to coalesce consecutive HumanMessage objects before they reach the model. Disable coalescing with coalesce=False.

API reference

DebounceConfig

Parameter Type Default Description
delay float 2.0 Quiet-period delay in seconds
max_wait float | None 10.0 Max buffering time. None = no limit
strategy Strategy TRAILING Debounce strategy

quieto

Method Description
push(message) Add a message to the buffer
next_batch() Await the next flushed batch
flush() Force-flush immediately
close() Close and flush pending messages
batches() Async iterator over batches
delay Get/set the delay (validates against max_wait)

@debounce

@debounce                          # defaults: delay=2.0, max_wait=10.0
@debounce(delay=1.0, max_wait=5.0) # custom config

# wrapper attributes:
handler.quieto  # access the quieto instance
handler.flush()    # force-flush
await handler.close()  # shut down

Development

# Install dependencies
uv sync --extra dev

# Run tests
uv run pytest tests/ -v

# Run tests with coverage
uv run pytest tests/ -v --cov=src --cov-report=term

# Lint
uv run ruff check src/ tests/

# Format
uv run ruff format src/ tests/

# Type check
uv run mypy src/

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quieto-0.1.1.tar.gz (73.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quieto-0.1.1-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file quieto-0.1.1.tar.gz.

File metadata

  • Download URL: quieto-0.1.1.tar.gz
  • Upload date:
  • Size: 73.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for quieto-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e5cab7698d2221ef7827123b0b9e59c4249b26d8d12feb6f73ea7f6567f39dfb
MD5 888a68dcf85fdbc80919bb141b223a39
BLAKE2b-256 f5c390270ee689678c17bd6c1ae65ff7e3ee378fe27707a2405c305c164e26c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for quieto-0.1.1.tar.gz:

Publisher: publish.yml on vnniciusg/quieto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quieto-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: quieto-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for quieto-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 eaf3e117085f341d0b17fb4f9fb27c4199e3245cec6a671b75ada95977c63f10
MD5 f17f638fdea55a4102d5a69735ce63c1
BLAKE2b-256 745dbd24f9c24303de7dd25792a6dc26112d9f65f40011429485986ac13c450f

See more details on using hashes here.

Provenance

The following attestation bundles were made for quieto-0.1.1-py3-none-any.whl:

Publisher: publish.yml on vnniciusg/quieto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page