Skip to content

User summary can fail when it starts before fact extraction finishes #40

Description

@coding-totoro

What happened

For a new user with no existing memories, the first user-summary run can fail because it starts at the same time as fact extraction.

At the 20-turn threshold, the change-feed handler starts ExtractMemoriesOrchestrator and UserSummaryOrchestrator independently. The user-summary activity retries three times with a two-second initial interval. If extraction has not persisted any facts yet, all attempts fail with:

ValidationError: No memories found for user_id='repro-user'

Extraction can then complete successfully, but the failed user summary is not retried automatically.

Why this matters

The first consolidated user profile can be missing even though turn ingestion and fact extraction both succeed. It requires an operator retry or waiting until a later summary threshold.

Reproduction

Use a Function app and toolkit built from the same current source revision (the separate package-pin problem is tracked in #39), then use a new user and thread with no existing memory records.

Write 20 turns quickly to memories_turns. With a configured async client, the write portion is:

for index in range(20):
    await client.upsert_memory(
        user_id="repro-user",
        thread_id="repro-thread",
        role="user" if index % 2 == 0 else "agent",
        content=f"Reproduction turn {index}",
        memory_type="turn",
        embed=False,
    )

Run the client with MEMORY_PROCESSOR_OWNER=durable so the change-feed Function owns processing. Then inspect these two Durable instances:

extract:repro-user:repro-thread:20
user_summary:repro-user:20

In a live reproduction:

  • Both orchestrations started in the same second.
  • UserSummaryOrchestrator failed after its short retry window with No memories found.
  • ExtractMemoriesOrchestrator completed about 21 seconds after it started and persisted facts.
  • Starting UserSummaryOrchestrator again after extraction completed succeeded immediately.

The current source still schedules the two orchestrations independently in function_app/triggers/change_feed.py. UserSummaryOrchestrator uses the shared retry policy of three attempts with a two-second initial interval.

Expected behavior

When the user-summary threshold is crossed, the summary should eventually be produced without manual intervention, even when extraction takes longer than the activity retry window.

Suggested resolution

Coordinate user-summary generation with successful memory persistence, or add a bounded Durable wait/retry specifically for the expected "no memories yet" condition. A regression test should delay extraction beyond the current retry window and confirm that the user summary still completes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions