Skip to main content

everalgo-boundary

Chat boundary detection for EverAlgo — segments a flat list of ChatMessage objects into coherent MemCell slices using an LLM-based batch algorithm.

See the umbrella project: EverAlgo monorepo and the architecture document at docs/concepts/architecture.md.

Install

pip install everalgo-boundary

For the user-scenario class facade, install everalgo-user-memory instead — it re-exports BoundaryDetector which wraps this package.

What this distribution provides

Symbol Role
detect_boundaries Low-level async function: (list[ChatMessage], *, llm, is_final, ...) → DetectionResult
DetectionResult NamedTuple(cells: list[MemCell], tail: list[ChatMessage])

The class-style facades (BoundaryDetector for user-scenario chat, AgentBoundaryDetector for agent trajectories with tool calls) live in everalgo-user-memory and everalgo-agent-memory respectively.

Quick start

import asyncio
import json

from everalgo.boundary import detect_boundaries
from everalgo.llm.types import ChatMessage as LLMChatMessage, ChatResponse
from everalgo.testing.fake_llm import FakeLLMClient
from everalgo.types import ChatMessage

_BOUNDARY_JSON = json.dumps(
    {"reasoning": "single topic", "boundaries": [], "should_wait": False}
)

async def main() -> None:
    fake = FakeLLMClient(responses=[ChatResponse(content=_BOUNDARY_JSON, model="fake")])
    messages = [
        ChatMessage(id="m1", role="user",   content="Let's talk about deployment.",     timestamp=1_700_000_000_000, sender_id="u_alice"),
        ChatMessage(id="m2", role="assistant", content="Sure — what's the target env?",  timestamp=1_700_000_001_000, sender_id="assistant"),
        ChatMessage(id="m3", role="user",   content="K8s. Switching topic: lunch?",     timestamp=1_700_000_002_000, sender_id="u_alice"),
    ]

    # Streaming: hold `tail` between calls; pass prior tail + new messages each time.
    result = await detect_boundaries(messages, llm=fake)
    cells, tail, should_wait = result  # NamedTuple unpacking

    # `should_wait` is the LLM's verdict on the tail, not a restatement of it being non-empty: True
    # means the trailing segment carries too little to place in an episode yet (media placeholders
    # only, a bare "ok", a system notification, an ambiguous 30-min-to-4-hour gap). A caller that
    # extracts on every non-empty tail extracts from those; one that waits on every non-empty tail
    # never extracts at all. `None` means no path judged it — see the DetectionResult docstring.

    # End-of-session: tail is forced into the last cell.
    result = await detect_boundaries(messages, llm=fake, is_final=True)
    assert result.tail == []
    for mc in result.cells:
        print(mc.timestamp, len(mc.items))


asyncio.run(main())

The streaming state machine

detect_boundaries deliberately holds back trailing messages as tail — the LLM cannot know whether a conversation continues beyond the last seen message. The caller maintains state:

tail: list[ChatMessage] = []

for batch in incoming_batches:
    result = await detect_boundaries(tail + batch, llm=client)
    await persist(result.cells)
    tail = result.tail

# Session ends — flush everything.
final = await detect_boundaries(tail, llm=client, is_final=True)
await persist(final.cells)

Tokenizer utilities

everalgo._tokenize (in everalgo-core) exposes two module-private utilities used by boundary algorithms; not part of the public surface:

  • count_tokens(text: str) → int — token count under OpenAI o200k_base encoding via tiktoken.
  • force_split(text: str, *, max_tokens: int) → list[str] — last-resort token-bounded chunking; no semantic awareness.

Stubs

WorkspaceMemCellExtractor (Jira / Email / Confluence) is a placeholder in v0.x — all methods raise NotImplementedError. It is deliberately excluded from everalgo.boundary.__all__; import it from everalgo.boundary.workspace directly if you need the reserved name. Implementation lands in a future minor bump when the RawData contract is finalised.

Related distributions

Metadata

Release files for everalgo-boundary 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for everalgo-boundary 0.3.0
File Size Uploaded
everalgo_boundary-0.3.0.tar.gz 23.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for everalgo-boundary 0.3.0
File Interpreter ABI Platform
everalgo_boundary-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.9 kB

Release files / everalgo_boundary-0.3.0.tar.gz

Download URL everalgo_boundary-0.3.0.tar.gz
Size 23.9 kB
Tags Source
SHA-256 checksum
How to use checksums
761c0ffdf4234bc641436db79d9211f809154580fb65178af3c9e64dd6bbd443
BLAKE2b-256 checksum
How to use checksums
57ba8cd039fdc848d45ade53a5db47a01a5db34b4664d0505b23c4adefc97d92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / everalgo_boundary-0.3.0-py3-none-any.whl

Download URL everalgo_boundary-0.3.0-py3-none-any.whl
Size 18.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6a037bb3ecf36ce07db4ad168757cbc6e745f5d1acf427ff10e0d827402b5e5
BLAKE2b-256 checksum
How to use checksums
2427fc7fc40581a0be93039764ef6e38de56fadd937bf93022ae10c179534c75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page