Catalog PyPI
PACKAGE EXPLORERView in registry

agentstate-reducer

PyPI

Framework-agnostic message reducer for AI agent state management. Works with LangGraph, CrewAI, and plain dicts.

Versions collected1
Direct dependencies9From release 0.5.0
Last observed20 Oct, 23:29 UTC

README

Version 0.5.0 documentation

agentstate-reducer

Framework-agnostic message reducer for AI agent state management. Works with LangGraph, CrewAI, and plain dicts.

What It Does

Automatically prunes message history when it exceeds a threshold, keeping conversations manageable:

  • Windowed pruning: Trigger at max_messages, retain min_messages
  • Token-budget pruning: Trigger at max_tokens, prune down to target_tokens — whole messages only, never truncated
  • System message preservation: Index 0 (system prompt) is never pruned (configurable)
  • ToolMessage cascade: When an AI message is pruned, linked ToolMessages are pruned too
  • Optional summarization: Callback with pruned messages to generate an LLM summary
  • Long-term memory hooks (on_prune) — new in 0.4.0: pruned messages are handed to any callable the moment they leave the window, with the app's memory namespace, exactly once. Wire them to a LangGraph BaseStore, LangMem, a Strands MemoryStore, or your own engine — the reducer imports none of them. See Long-Term Memory Hooks.
  • Role alias normalisation: Understands user/assistant/agent in addition to human/ai — works with OpenAI-format dicts and agent framework outputs out of the box
  • Framework-agnostic: Works with plain dicts, LangChain BaseMessage subclasses, or any duck-typed message object — zero dependencies

Install

pip install agentstate-reducer

Zero dependencies. Works with Python 3.10+.

Quick Start

from agentstate_reducer import MessageReducer

reducer = MessageReducer(min_messages=10, max_messages=20)

# Works with plain dicts
result = reducer.reduce(
    existing=[
        {"role": "system", "content": "You are helpful"},
        {"role": "human", "content": "Hello"},
        {"role": "ai", "content": "Hi there!"},
    ],
    new=[{"role": "human", "content": "New message"}],
)
print(result.surviving)  # Messages that remain
print(result.pruned)     # Messages that were removed

# Works with LangChain BaseMessage objects too
from langchain_core.messages import HumanMessage, AIMessage
result = reducer.reduce(
    existing=[HumanMessage(content="Hello")],
    new=[AIMessage(content="Hi!")],
)

LangGraph Integration

Use directly as a state annotation — the reducer runs automatically on every state update:

from agentstate_reducer import MessageReducer
from typing_extensions import Annotated, TypedDict

reducer = MessageReducer(min_messages=10, max_messages=20)

class MyState(TypedDict):
    messages: Annotated[list, reducer.as_langgraph_reducer()]

as_langgraph_reducer() returns a (existing, new) -> list function that LangGraph calls on every state merge.

Any LangGraph Checkpointer, Bounded (ReducingSaver)

Checkpoint storage grows on two axes: how many checkpoints you keep (prune, TTL) and how big each one is. The messages channel is stored whole on every step, so a thread's blobs grow quadratically with its length, and keep-latest never shrinks the latest one. ReducingSaver runs the reducer inside any saver's put, so every checkpoint holds at most max_messages messages and the pruned turns go to on_prune once each:

pip install "agentstate-reducer[langgraph]"
from langgraph.checkpoint.postgres import PostgresSaver
from agentstate_reducer import MessageReducer, ReducerConfig
from agentstate_reducer.langgraph import ReducingSaver

saver = ReducingSaver(PostgresSaver.from_conn_string(url), MessageReducer(config=ReducerConfig(max_messages=20)))
graph = builder.compile(checkpointer=saver)

Works with PostgresSaver, SQLite, MongoDB, Redis, in-memory. Wrapping one of the agentstate checkpointers (DynamoDB, Cosmos DB, Firestore) hands the reducer to the saver instead, so it still runs once; wrapping a saver that already has a different reducer raises. Optional capabilities (copy_thread, delete_for_runs, prune) are delegated only when the inner saver implements them. Not for DeltaChannel-backed message channels. Docs: Any Checkpointer, Bounded.

CosmosDB Checkpoint Integration

When using langgraph-checkpoint-cosmosdb, pass a MessageReducer to reduce messages at the persistence layer — useful when you don't control the state definition:

from agentstate_reducer import MessageReducer
from langgraph_checkpoint_cosmosdb import CosmosDBSaver

reducer = MessageReducer(min_messages=10, max_messages=20)
saver = CosmosDBSaver(
    database_name="mydb",
    container_name="checkpoints",
    reducer=reducer,           # applied before each checkpoint is stored
    messages_key="messages",   # which channel holds the message list (default)
)

Summarization

Provide a summarize_fn to generate a summary of pruned messages (e.g. via an LLM):

from agentstate_reducer import MessageReducer, ReducerConfig

def summarize(pruned_messages):
    # Call your LLM here
    return f"Summary of {len(pruned_messages)} pruned messages"

config = ReducerConfig(
    min_messages=10,
    max_messages=20,
    summarize_fn=summarize,
)
reducer = MessageReducer(config=config)
result = reducer.reduce(existing=messages)
print(result.summary)  # "Summary of 5 pruned messages"

result.summary is always returned when a summarize_fn is set — you can store or display it however you like.

Injecting the summary back into the conversation

By default the summary is only returned, not added to the surviving messages. Set inject_summary=True to also insert it in place of the pruned block, so the model sees it on the next turn:

config = ReducerConfig(
    min_messages=10,
    max_messages=20,
    summarize_fn=summarize,
    inject_summary=True,
)

The default injection is a human + ai pair — a human message carrying the summary followed by a short ai acknowledgement ("OK"):

[system] → [human: "Here is the summary of previous N messages: ..."] → [ai: "OK"] → [recent tail]

Why a pair? It keeps the conversation well-formed for providers that require strict role alternation (system → human → ai → …). Because both messages are ordinary human/ai messages at the front of the window, the next prune sweeps them into the new summary automatically — so there is always exactly one summary block, with no accumulation and no bookkeeping.

Custom shape. Override summary_message_factory — a Callable[[summary_text, pruned_count], list[message]] — to inject a single message or a provider-specific shape:

config = ReducerConfig(
    summarize_fn=summarize,
    inject_summary=True,
    # inject just one system message instead of the human/ai pair
    summary_message_factory=lambda text, n: [{"role": "system", "content": f"Summary ({n} msgs): {text}"}],
)

The summary is placed where the pruned messages were — after preserve_first, before the retained recent tail — never at index 0 (the system prompt is preserved). When used with a checkpoint/persistence saver that stores result.surviving, the injected summary is persisted automatically with no saver changes.

Long-Term Memory Hooks (on_prune)

Messages leaving the window are exactly the ones worth deciding about for long-term memory. on_prune hands them to any callable the moment they are pruned — the reducer never imports a store, a framework, or an LLM, so it stays zero-dependency and the same hook body works for every framework that runs the reducer (LangGraph checkpointers, CrewAI persistence, ...).

from agentstate_reducer import MessageReducer, ReducerConfig, Background

def remember(pruned, namespace):
    # namespace is whatever the framework integration forwarded (see below)
    for m in pruned:
        store.put(namespace, key=str(uuid4()), value={"role": m.type, "content": m.content})

reducer = MessageReducer(config=ReducerConfig(
    max_messages=20,
    on_prune=[remember],              # cheap hook: runs inline
    # on_prune=[Background(remember)]  # slow hook (LLM extraction): runs off the request path
))

Where the namespace comes from. reduce(..., namespace=X) forwards X untouched to every hook. Framework integrations look up ReducerConfig.namespace_key (default "memory_namespace") in their per-call config and pass that — e.g. in LangGraph:

graph.invoke(input, config={"configurable": {
    "thread_id": uuid4().hex,                       # short-term scope (checkpoint)
    "memory_namespace": ("memories", user.id),      # long-term scope (store)
}})

If the app never sets it, integrations fall back to a per-thread namespace. Old callers that pass no namespace get None.

Exactly once. Persistence layers often call reduce() several times per turn on overlapping lists (LangGraph writes a checkpoint per super-step). With dedupe_on_prune=True (default) each message id reaches the hooks once per reducer instance; ReducerResult.pruned is never filtered.

Background(fn, workers=2, max_pending=1000) runs a hook on a bounded worker pool: copies the list, drops (with a warning) when the backlog is full, swallows hook exceptions, drains at exit. On serverless runtimes call close() at the end of the handler.

Token-Budget Pruning

Instead of counting messages, you can prune to a token budget — useful when you want to stay within a model's context window or control cost. Set max_tokens and pruning switches from message-count mode to token mode.

from agentstate_reducer import MessageReducer, ReducerConfig

# Prune when the conversation exceeds 4000 tokens, down to ~2000
config = ReducerConfig(max_tokens=4000, target_tokens=2000)
reducer = MessageReducer(config=config)

result = reducer.reduce(existing=messages, new=new_messages)
# result.surviving stays within ~2000 tokens; whole messages only — never truncated

Whole messages only. The reducer never truncates message content — it drops whole messages, keeping the most recent ones that fit the budget, plus the preserved first message. This guarantees you never send a model a half-cut message.

max_tokens vs target_tokens. Pruning triggers when the total exceeds max_tokens, and reduces down to target_tokens (defaults to max_tokens if not set). Setting target_tokens lower than max_tokens creates hysteresis — prune at 4000, down to 2000 — so pruning runs less often.

How tokens are counted

The counter is resolved in three layers (highest priority first):

  1. User-supplied token_counter — a Callable[[message], int] you pass on the config. Use this for exact, model-specific counting:
    import tiktoken
    enc = tiktoken.encoding_for_model("gpt-4o")
    config = ReducerConfig(
        max_tokens=4000,
        token_counter=lambda m: len(enc.encode(m.get("content", ""))),
    )
    
  2. tiktoken — if installed (pip install "agentstate-reducer[tokens]"), the cl100k_base encoding is used automatically. Accurate for OpenAI-family models.
  3. Character heuristic — len(content) / 4 plus a small per-message overhead. Dependency-free fallback, fine for approximate budgeting.

Install with tiktoken support:

pip install "agentstate-reducer[tokens]"

Token mode takes precedence over message-count mode: if max_tokens is set, max_messages/min_messages are ignored. preserve_first and cascade_tool_messages apply in both modes.

Pruning Behaviour

  • Only ai/agent/assistant and human/user messages are candidates for pruning.
  • system, tool, and function messages are never pruned directly.
  • Index 0 is preserved by default (preserve_first=True) — typically the system prompt.
  • When an ai message is pruned, all tool messages linked to it via tool_call_id are also pruned (cascade_tool_messages=True).
  • Pruning is windowed: once len(existing + new) > max_messages, oldest eligible messages are removed until min_messages remain.

Role Aliases

The reducer normalises common role name variants before applying pruning rules, so you don't need to convert message formats:

Input roleTreated asCommon source
humanhumanLangChain canonical
userhumanOpenAI API format
aiaiLangChain canonical
assistantaiOpenAI API format
agentaiLangGraph task outputs, agent frameworks
systemsystempreserved, never pruned
tooltoolpreserved unless cascade-pruned

This means OpenAI-format message lists (role: "user" / role: "assistant") work without any preprocessing.

Framework Compatibility

The adapter layer uses duck typing and class-name inspection — no langchain_core import required:

Message formatSupported
{"role": "ai", "content": "..."}✓ plain dict with role key
{"role": "user", "content": "..."}✓ OpenAI-format dict (normalised to human)
{"role": "agent", "content": "..."}✓ agent framework dict (normalised to ai)
{"type": "ai", "content": "..."}✓ plain dict with type key (LangChain serialized)
AIMessage, HumanMessage, etc.✓ LangChain BaseMessage subclasses
Any object with .type attribute✓ duck typing fallback

API Reference

MessageReducer(min_messages, max_messages, *, config)

ParamDefaultDescription
min_messages0Messages to retain after pruning
max_messagesNoneThreshold to trigger pruning (None = never prune)
configNoneReducerConfig object (overrides min_messages/max_messages)

ReducerConfig

FieldDefaultDescription
min_messages10Messages to retain after pruning (message-count mode)
max_messages20Threshold to trigger pruning (message-count mode)
max_tokensNoneToken threshold to trigger pruning. When set, enables token mode (takes precedence over message-count mode)
target_tokensNonePrune down to at or below this token count. Defaults to max_tokens
token_counterNoneCallable[[message], int]. When omitted: tiktoken if installed, else char heuristic
preserve_firstTrueNever prune index 0 (system message)
cascade_tool_messagesTrueAlso prune ToolMessages linked to a pruned AIMessage
summarize_fnNoneCallable[[list], str] called with pruned messages
inject_summaryFalseInsert the summary back into surviving in place of the pruned block
on_prune[]RememberFn list: (pruned, namespace) -> Any, called after pruning
namespace_key"memory_namespace"Key integrations read from per-call config to find the namespace
dedupe_on_pruneTrueDeliver each message id to hooks at most once per reducer instance
dedupe_window10000Bounded memory of delivered ids

reducer.reduce(existing, new, namespace=None) -> ReducerResult

FieldTypeDescription
survivinglistMessages that remain
prunedlistMessages that were removed
summarystr | NoneSummary from summarize_fn if configured

reducer.as_langgraph_reducer() -> Callable

Returns a function with signature (existing, new) -> list for use with LangGraph's Annotated[list, fn] pattern.

Downloads & popularity

3downloads
1-day window · source-reported counts20 Oct 2026
2061030
2026-07-23: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-23–2026-07-232026-07-26: 100 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-26–2026-07-262026-07-27: 13 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-27–2026-07-272026-07-28: 10 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-28–2026-07-282026-07-29: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-29–2026-07-292026-07-30: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-30–2026-07-302026-07-31: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-07-31–2026-07-312026-08-01: 6 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-01–2026-08-012026-08-02: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-02–2026-08-022026-08-03: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-03–2026-08-032026-08-04: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-04–2026-08-042026-08-06: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-06–2026-08-062026-08-07: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-07–2026-08-072026-08-09: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-09–2026-08-092026-08-10: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-10–2026-08-102026-08-12: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-12–2026-08-122026-08-13: 34 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-13–2026-08-132026-08-14: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-14–2026-08-142026-08-15: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-15–2026-08-152026-08-16: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-16–2026-08-162026-08-17: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-17–2026-08-172026-08-18: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-18–2026-08-182026-08-19: 6 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-19–2026-08-192026-08-20: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-20–2026-08-202026-08-21: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-21–2026-08-212026-08-23: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-23–2026-08-232026-08-24: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-24–2026-08-242026-08-25: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-25–2026-08-252026-08-27: 8 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-27–2026-08-272026-08-28: 19 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-28–2026-08-282026-08-31: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-08-31–2026-08-312026-09-01: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-01–2026-09-012026-09-03: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-03–2026-09-032026-09-04: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-04–2026-09-042026-09-06: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-06–2026-09-062026-09-07: 42 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-07–2026-09-072026-09-08: 206 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-08–2026-09-082026-09-09: 48 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-09–2026-09-092026-09-10: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-10–2026-09-102026-09-11: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-11–2026-09-112026-09-12: 6 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-12–2026-09-122026-09-13: 9 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-13–2026-09-132026-09-14: 7 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-14–2026-09-142026-09-16: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-16–2026-09-162026-09-18: 94 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-18–2026-09-182026-09-19: 9 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-19–2026-09-192026-09-20: 11 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-20–2026-09-202026-09-21: 103 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-21–2026-09-212026-09-22: 10 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-22–2026-09-222026-09-23: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-23–2026-09-232026-09-24: 7 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-24–2026-09-242026-09-25: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-25–2026-09-252026-09-26: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-26–2026-09-262026-09-27: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-27–2026-09-272026-09-28: 8 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-28–2026-09-282026-09-29: 10 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-29–2026-09-292026-09-30: 12 · observed 2026-10-21T10:29:26.7027563Z · period 2026-09-30–2026-09-302026-10-01: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-01–2026-10-012026-10-02: 1 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-02–2026-10-022026-10-04: 4 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-04–2026-10-042026-10-05: 9 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-05–2026-10-052026-10-06: 15 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-06–2026-10-062026-10-07: 13 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-07–2026-10-072026-10-08: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-08–2026-10-082026-10-09: 10 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-09–2026-10-092026-10-10: 10 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-10–2026-10-102026-10-11: 5 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-11–2026-10-112026-10-12: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-12–2026-10-122026-10-13: 2 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-13–2026-10-132026-10-14: 7 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-14–2026-10-142026-10-15: 8 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-15–2026-10-152026-10-16: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-16–2026-10-162026-10-17: 15 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-17–2026-10-172026-10-18: 13 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-18–2026-10-182026-10-19: 7 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-19–2026-10-192026-10-20: 3 · observed 2026-10-21T10:29:26.7027563Z · period 2026-10-20–2026-10-20
23 Jul20 Oct

pypistats · 76 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-20 – 2026-10-2032026-10-21T10:29:26.7027563Z
2026-10-19 – 2026-10-1972026-10-21T10:29:26.7027563Z
2026-10-18 – 2026-10-18132026-10-21T10:29:26.7027563Z
2026-10-17 – 2026-10-17152026-10-21T10:29:26.7027563Z
2026-10-16 – 2026-10-1632026-10-21T10:29:26.7027563Z
2026-10-15 – 2026-10-1582026-10-21T10:29:26.7027563Z
2026-10-14 – 2026-10-1472026-10-21T10:29:26.7027563Z
2026-10-13 – 2026-10-1322026-10-21T10:29:26.7027563Z
2026-10-12 – 2026-10-1222026-10-21T10:29:26.7027563Z
2026-10-11 – 2026-10-1152026-10-21T10:29:26.7027563Z
2026-10-10 – 2026-10-10102026-10-21T10:29:26.7027563Z
2026-10-09 – 2026-10-09102026-10-21T10:29:26.7027563Z
2026-10-08 – 2026-10-0822026-10-21T10:29:26.7027563Z
2026-10-07 – 2026-10-07132026-10-21T10:29:26.7027563Z
2026-10-06 – 2026-10-06152026-10-21T10:29:26.7027563Z
2026-10-05 – 2026-10-0592026-10-21T10:29:26.7027563Z
2026-10-04 – 2026-10-0442026-10-21T10:29:26.7027563Z
2026-10-02 – 2026-10-0212026-10-21T10:29:26.7027563Z
2026-10-01 – 2026-10-0152026-10-21T10:29:26.7027563Z
2026-09-30 – 2026-09-30122026-10-21T10:29:26.7027563Z
2026-09-29 – 2026-09-29102026-10-21T10:29:26.7027563Z
2026-09-28 – 2026-09-2882026-10-21T10:29:26.7027563Z
2026-09-27 – 2026-09-2712026-10-21T10:29:26.7027563Z
2026-09-26 – 2026-09-2632026-10-21T10:29:26.7027563Z
2026-09-25 – 2026-09-2522026-10-21T10:29:26.7027563Z
2026-09-24 – 2026-09-2472026-10-21T10:29:26.7027563Z
2026-09-23 – 2026-09-2312026-10-21T10:29:26.7027563Z
2026-09-22 – 2026-09-22102026-10-21T10:29:26.7027563Z
2026-09-21 – 2026-09-211032026-10-21T10:29:26.7027563Z
2026-09-20 – 2026-09-20112026-10-21T10:29:26.7027563Z
2026-09-19 – 2026-09-1992026-10-21T10:29:26.7027563Z
2026-09-18 – 2026-09-18942026-10-21T10:29:26.7027563Z
2026-09-16 – 2026-09-1642026-10-21T10:29:26.7027563Z
2026-09-14 – 2026-09-1472026-10-21T10:29:26.7027563Z
2026-09-13 – 2026-09-1392026-10-21T10:29:26.7027563Z
2026-09-12 – 2026-09-1262026-10-21T10:29:26.7027563Z
2026-09-11 – 2026-09-1112026-10-21T10:29:26.7027563Z
2026-09-10 – 2026-09-1012026-10-21T10:29:26.7027563Z
2026-09-09 – 2026-09-09482026-10-21T10:29:26.7027563Z
2026-09-08 – 2026-09-082062026-10-21T10:29:26.7027563Z
2026-09-07 – 2026-09-07422026-10-21T10:29:26.7027563Z
2026-09-06 – 2026-09-0612026-10-21T10:29:26.7027563Z
2026-09-04 – 2026-09-0422026-10-21T10:29:26.7027563Z
2026-09-03 – 2026-09-0312026-10-21T10:29:26.7027563Z
2026-09-01 – 2026-09-0152026-10-21T10:29:26.7027563Z
2026-08-31 – 2026-08-3112026-10-21T10:29:26.7027563Z
2026-08-28 – 2026-08-28192026-10-21T10:29:26.7027563Z
2026-08-27 – 2026-08-2782026-10-21T10:29:26.7027563Z
2026-08-25 – 2026-08-2552026-10-21T10:29:26.7027563Z
2026-08-24 – 2026-08-2452026-10-21T10:29:26.7027563Z
2026-08-23 – 2026-08-2332026-10-21T10:29:26.7027563Z
2026-08-21 – 2026-08-2112026-10-21T10:29:26.7027563Z
2026-08-20 – 2026-08-2042026-10-21T10:29:26.7027563Z
2026-08-19 – 2026-08-1962026-10-21T10:29:26.7027563Z
2026-08-18 – 2026-08-1822026-10-21T10:29:26.7027563Z
2026-08-17 – 2026-08-1742026-10-21T10:29:26.7027563Z
2026-08-16 – 2026-08-1622026-10-21T10:29:26.7027563Z
2026-08-15 – 2026-08-1522026-10-21T10:29:26.7027563Z
2026-08-14 – 2026-08-1452026-10-21T10:29:26.7027563Z
2026-08-13 – 2026-08-13342026-10-21T10:29:26.7027563Z
2026-08-12 – 2026-08-1222026-10-21T10:29:26.7027563Z
2026-08-10 – 2026-08-1022026-10-21T10:29:26.7027563Z
2026-08-09 – 2026-08-0942026-10-21T10:29:26.7027563Z
2026-08-07 – 2026-08-0712026-10-21T10:29:26.7027563Z
2026-08-06 – 2026-08-0632026-10-21T10:29:26.7027563Z
2026-08-04 – 2026-08-0422026-10-21T10:29:26.7027563Z
2026-08-03 – 2026-08-0332026-10-21T10:29:26.7027563Z
2026-08-02 – 2026-08-0212026-10-21T10:29:26.7027563Z
2026-08-01 – 2026-08-0162026-10-21T10:29:26.7027563Z
2026-07-31 – 2026-07-3142026-10-21T10:29:26.7027563Z
2026-07-30 – 2026-07-3042026-10-21T10:29:26.7027563Z
2026-07-29 – 2026-07-2922026-10-21T10:29:26.7027563Z
2026-07-28 – 2026-07-28102026-10-21T10:29:26.7027563Z
2026-07-27 – 2026-07-27132026-10-21T10:29:26.7027563Z
2026-07-26 – 2026-07-261002026-10-21T10:29:26.7027563Z
2026-07-23 – 2026-07-2352026-10-21T10:29:26.7027563Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.5.021 Sept 20269

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
skamalj/agentstate-reducer

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 23:29 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:2835aec3c9cd0080314901dcdb1510cb82ab076ea040fa374e8885a696fb40f1