Project link
https://github.com/xmemory-ai/temporal-xmemory-events-agent
Language
Python
Short description (max 256 chars)
Long-running AI agents that research AI events for months on end. Temporal makes every model call, web fetch and memory write a durable Activity and resumes the cycle after a crash; xmemory keeps their findings as shared records anyone can query.
Long Description
Long-running AI agents that research AI conferences, meetups, hackathons and summits for months on end, and keep what they learn in a shared memory that people and other agents query in plain language. Temporal keeps the cycle running through worker crashes and redeploys; xmemory turns each agent's prose into structured, queryable records and enforces the domain rules of the shared state.

What it does
The recurring job is real: find upcoming AI events, collect the details a team needs to decide where to participate, and keep that catalogue current. Two agents divide the work.
| Agent |
Does |
Writes |
| Discovery |
Searches the web, deadline directories and event platforms |
Each event it finds: canonical name, website, where it was found |
| Processor |
Crawls one waiting event's pages |
Dates, venue, call for papers, registration, prices, topics, and the status processed or failed |
Both are built on the OpenAI Agents SDK with tools for web search, page fetching and memory. Inside a stage the model decides what to search, fetch and write; the only fixed structure is the cycle around it.
Agents build the catalogue of events, deadlines and topics; people add attendance plans. After a cycle completes, its findings remain available for questions such as "Which conferences in Europe have an open call for papers?" or "Who is attending an event in December?", and the answer comes from the records, not from a transcript.
A domain constraint the memory enforces: one event per person, per day
The schema expresses attendance as a three-part relation connecting TeamMember, CalendarDay and Event. A person enters one sentence:

xmemory interprets it as a link between three records. The date describes this person's attendance: a conference may run for several days while a teammate attends one, and the event's own dates stay on the shared Event record. The relation's uniqueness key covers the attendee and the date, so assigning the same person to a different event on the same day is a conflict, declared directly in the memory schema:
attendance:
objects:
attendee: {type: TeamMember}
date: {type: CalendarDay}
event: {type: Event}
keys:
one_event_per_person_per_day: [date, attendee]
| Another attendance statement |
What the key means |
| Maya Chen attends ExampleConf 2027 on 2027-03-04. |
A different date permits a separate link. |
| Leo Martin attends ExampleConf 2027 on 2027-03-03. |
A different attendee permits a separate link. |
| Maya Chen attends another event on 2027-03-03. |
The same attendee and date cannot hold two event links. |
A backend test asserts that one attendance link remains after a conflicting write. A second memory instance stores run logs and notes about useful sources, so the two instances hold both the team's event knowledge and the agents' experience of researching it.
Shared state makes the hand-off explicit
The agents never call each other; the memory is the hand-off.

Discovery writes an event without a processing status and without looking it up first: its tool list has memory writes and coordination-board reads, and no event lookup. xmemory resolves records by the canonical event name, so a second mention updates the record instead of duplicating it. The workflow reads the records still waiting and passes each to a Processor, which adds the researched details and marks the event processed or failed.
processing_status deliberately has no schema default: rediscovering an event, or recording someone's attendance, leaves its existing status intact. A regression test checks that a later discovery preserves the processed status and the researched dates.
How it uses Temporal
An always-alive workflow orchestrates the two agents through Temporal's OpenAI Agents SDK integration and xmemory's Temporal integration. Each cycle follows a small, explicit sequence:
- Open a run and launch Discovery as a child workflow.
- Query the events memory for records waiting to be processed.
- Launch a Processor child workflow for each event, limiting how many run at once.
- Record the outcome and Continue-As-New, carrying execution forward with a fresh history.
| Pattern |
Where |
Why it matters |
Entity workflow, state set in @workflow.init, cadence via wait_condition with a timeout, continue_as_new after every cycle |
workflows/scout.py |
The loop runs for months with a history that never grows beyond one cycle |
Signals run_now, pause, resume, stop, instruct and the status query, consumed by the wait loop |
same |
Unattended, yet steerable from the CLI while it runs |
Child workflows with ids {workflow_id}-{run_id}-{stage}, per-child run_timeout, semaphore-bounded fan-out |
same |
A retried task or a replay cannot start a duplicate child; a failed child is recorded, never fatal |
| Model calls as Activities |
workflows/stage_runner.py |
On replay the stored response is returned; the model is not invoked again |
| Memory writes as one enqueue Activity plus idempotent status polls |
agents/tools.py |
A worker restart resumes the wait instead of re-submitting the text |
Model calls, page fetches and memory operations do their external work through Activities. In the agent's memory tool the integration is one call:
status = await _events(ctx).write_durable(
text, extraction_logic="deep", max_wait=WRITE_MAX_WAIT, max_poll_interval=WRITE_MAX_POLL_INTERVAL
)
The call starts the extraction and waits for its result through a workflow-managed polling loop; once the write id is recorded, the wait resumes after a worker restart, and Temporal reuses Activity results already in history during replay. Retrying an unfinished write is treated as a separate concern: the write policy excludes server, availability and unknown errors from automatic retries, because the record's key is extracted from the text and a second extraction could fork the record, and the tool tells the agent to report a failed write without resubmitting the same text. A forced-replay test runs a stage with max_cached_workflows=0 and asserts the enqueue is scheduled exactly once per write.
Who it's for
Developers building agents whose work never finishes, runs unattended, or is shared between several agents, and who want a worked example of the division of labour: Temporal holds the cursor of the work in progress, xmemory holds what is known, and the agents hold nothing. The broader pattern is reusable: define the identity and update rules for the knowledge, make hand-offs visible in shared state, and let Temporal orchestrate the work that changes it.
The repository is small enough to read in an afternoon and is tested at three levels: unit tests without credentials, memory-backed tests that run the real workflows on a local Temporal dev server against real xmemory instances with a scripted model, and a live test with a real model against the real web.
Getting started
The README's step-by-step guide covers install, credentials, configuration, creating the two memory instances, and running the Temporal dev server, the worker and the entity. It also states the requirements and costs: an OpenAI API key, an xmemory API key and the Temporal CLI; there is no keyless demo.
Author(s)
Alexander Gusak (LI: https://www.linkedin.com/in/agusak/), founding engineer at xmemory.ai
Project link
https://github.com/xmemory-ai/temporal-xmemory-events-agent
Language
Python
Short description (max 256 chars)
Long-running AI agents that research AI events for months on end. Temporal makes every model call, web fetch and memory write a durable Activity and resumes the cycle after a crash; xmemory keeps their findings as shared records anyone can query.
Long Description
Long-running AI agents that research AI conferences, meetups, hackathons and summits for months on end, and keep what they learn in a shared memory that people and other agents query in plain language. Temporal keeps the cycle running through worker crashes and redeploys; xmemory turns each agent's prose into structured, queryable records and enforces the domain rules of the shared state.
What it does
The recurring job is real: find upcoming AI events, collect the details a team needs to decide where to participate, and keep that catalogue current. Two agents divide the work.
processedorfailedBoth are built on the OpenAI Agents SDK with tools for web search, page fetching and memory. Inside a stage the model decides what to search, fetch and write; the only fixed structure is the cycle around it.
Agents build the catalogue of events, deadlines and topics; people add attendance plans. After a cycle completes, its findings remain available for questions such as "Which conferences in Europe have an open call for papers?" or "Who is attending an event in December?", and the answer comes from the records, not from a transcript.
A domain constraint the memory enforces: one event per person, per day
The schema expresses attendance as a three-part relation connecting TeamMember, CalendarDay and Event. A person enters one sentence:
xmemory interprets it as a link between three records. The date describes this person's attendance: a conference may run for several days while a teammate attends one, and the event's own dates stay on the shared Event record. The relation's uniqueness key covers the attendee and the date, so assigning the same person to a different event on the same day is a conflict, declared directly in the memory schema:
A backend test asserts that one attendance link remains after a conflicting write. A second memory instance stores run logs and notes about useful sources, so the two instances hold both the team's event knowledge and the agents' experience of researching it.
Shared state makes the hand-off explicit
The agents never call each other; the memory is the hand-off.
Discovery writes an event without a processing status and without looking it up first: its tool list has memory writes and coordination-board reads, and no event lookup. xmemory resolves records by the canonical event name, so a second mention updates the record instead of duplicating it. The workflow reads the records still waiting and passes each to a Processor, which adds the researched details and marks the event
processedorfailed.processing_statusdeliberately has no schema default: rediscovering an event, or recording someone's attendance, leaves its existing status intact. A regression test checks that a later discovery preserves the processed status and the researched dates.How it uses Temporal
An always-alive workflow orchestrates the two agents through Temporal's OpenAI Agents SDK integration and xmemory's Temporal integration. Each cycle follows a small, explicit sequence:
@workflow.init, cadence viawait_conditionwith a timeout,continue_as_newafter every cycleworkflows/scout.pyrun_now,pause,resume,stop,instructand thestatusquery, consumed by the wait loop{workflow_id}-{run_id}-{stage}, per-childrun_timeout, semaphore-bounded fan-outworkflows/stage_runner.pyagents/tools.pyModel calls, page fetches and memory operations do their external work through Activities. In the agent's memory tool the integration is one call:
The call starts the extraction and waits for its result through a workflow-managed polling loop; once the write id is recorded, the wait resumes after a worker restart, and Temporal reuses Activity results already in history during replay. Retrying an unfinished write is treated as a separate concern: the write policy excludes server, availability and unknown errors from automatic retries, because the record's key is extracted from the text and a second extraction could fork the record, and the tool tells the agent to report a failed write without resubmitting the same text. A forced-replay test runs a stage with
max_cached_workflows=0and asserts the enqueue is scheduled exactly once per write.Who it's for
Developers building agents whose work never finishes, runs unattended, or is shared between several agents, and who want a worked example of the division of labour: Temporal holds the cursor of the work in progress, xmemory holds what is known, and the agents hold nothing. The broader pattern is reusable: define the identity and update rules for the knowledge, make hand-offs visible in shared state, and let Temporal orchestrate the work that changes it.
The repository is small enough to read in an afternoon and is tested at three levels: unit tests without credentials, memory-backed tests that run the real workflows on a local Temporal dev server against real xmemory instances with a scripted model, and a live test with a real model against the real web.
Getting started
The README's step-by-step guide covers install, credentials, configuration, creating the two memory instances, and running the Temporal dev server, the worker and the entity. It also states the requirements and costs: an OpenAI API key, an xmemory API key and the Temporal CLI; there is no keyless demo.
Author(s)
Alexander Gusak (LI: https://www.linkedin.com/in/agusak/), founding engineer at xmemory.ai