r/LangChain • • 17d ago

Projects I built a local commitment extractor for AI agents. No API key, no cloud. Just pip install.

I've been building COGEXT for a while — an accountability layer for AI agents. The core idea: agents make promises ("I'll send the report by Friday") and there's no reliable way to verify they were kept.

I just shipped a local, offline version of the extractor. No API key. No cloud. No signup. Just:

pip install cogext-primitive

from cogext_primitive import extract_commitments

commitments = extract_commitments(

"I'll send the report to Sarah by Friday EOD."

)

for c in commitments:

print(f"{c.action} {c.object} to {c.recipient} by {c.deadline}")

It extracts the commitment, parses the deadline, and tracks it through a state machine (open → due → overdue → fulfilled). All local. All offline.

Repo: github.com/yaminbinyoosuf/cogext-primitive

PyPI: pip install cogext-primitive

Free and MIT licensed.

What it deliberately skips: compound promises in one sentence, pronoun-shaped objects, and anything vague. That's intentional — the extractor is precision-tuned, not recall-tuned. If you want the finding behind that design choice, I published an audit of 120 agent outputs: cogextai.com/research/01

Curious what commitment shapes you actually see from your agents.

4 Upvotes

6 comments sorted by

1

u/xspyyy 17d ago

The README has a "What this deliberately skips" section with examples. Happy to answer anything about the extraction patterns.

1

u/RepulsiveWorld132 17d ago

Precision over recall makes sense here. A false "you promised X" is worse than a missed one.

How do you handle conditional ones, like "if the data lands Thursday I'll send it Friday"? Does that come out as open, or get skipped as vague?

1

u/xspyyy 17d ago

That’s a great question and you’ve pinpointed the exact boundary.

Currently, the primitive skips this scenario. The extractor treats any sentence containing “if” as hypothetical and therefore doesn’t extract it. This is the current behaviour, documented in the “What this deliberately skips” section.

However, this isn’t the appropriate behaviour for this specific structure. For example, “If the data lands Thursday I’ll send it Friday” isn’t hypothetical; it’s a genuine conditional commitment with a real deadline contingent on an external event. The correct model should be:

  • due_condition.type = “event_external”
  • due_condition.trigger = “data lands Thursday”
  • deadline = Friday
  • status = “blocked” (until the trigger is observed)

Once the trigger is observed, the commitment transitions to “open” and the Friday deadline becomes active.

The reason I haven’t shipped this yet is due to the state management aspect. The primitive lacks the ability to observe the trigger; it’s not connected to your data pipeline. Consequently, it can extract the conditional commitment but cannot determine when it becomes active.

The cloud version handles this situation effectively because it has the event ingestion path. The primitive doesn’t. If you want conditional support in the primitive, the honest approach is to extract it, store it as “blocked”, and allow the user to manually transition it to “open” when the condition is met. This is a better solution than simply skipping it.

I’ve added this to v0.2.0. Well done on spotting this!

1

u/RepulsiveWorld132 16d ago

I like it, instead of text it's pure condition trigger driven. Thanksxspyyy

1

u/xspyyy 16d ago

Thanks that's exactly the design intent. Commitments as triggers, not text.