Skip to content

make runs persistent#33

Open
pmeier wants to merge 7 commits into
mainfrom
run-persistence
Open

make runs persistent#33
pmeier wants to merge 7 commits into
mainfrom
run-persistence

Conversation

@pmeier
Copy link
Copy Markdown
Member

@pmeier pmeier commented May 13, 2026

AG-UI supports branching and time-travel on a per-run basis. So far ravnar has no concept of a run beyond the name being used in the endpoint that kicks on off. This PR introduces a persistent run object, with each thread being a tree of runs. This is optional and client can still use a linear history. Any BC breaking changes are called out below.

@pmeier pmeier marked this pull request as ready for review May 13, 2026 22:02
_, _, messages = await database.get_thread_history(user_id=user.id, thread_id=thread_id, run_id=run_id)
return pydantic.TypeAdapter(list[schema.AugmentedMessage]).validate_python(messages, from_attributes=True)

@router.sse("/{threadId}/runs", methods=["POST"], response_model=schema.Event, tags=["Runs"])
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only intended BC break:

  • old: POST {threadId}/run
  • new: POST {threadId}/runs

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the impetus for the change? IMHO a POST endpoint should be a verb, not a noun.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runs are now a proper object. So this becomes a regular CRUD endpoint alongside

  • GET /api/threads/{threadId}/runs
  • GET /api/threads/{threadId}/runs/{runId}

@sccolbert
Copy link
Copy Markdown
Collaborator

I've made one comment so far, but this is a big PR. Could you please provide some commentary on its purpose and what we achieve by adopting it?

Comment thread src/_ravnar/schema/api.py
name: str | None = None
agent_id: str
created_at: datetime
updated_at: datetime
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A thread is never updated anymore, but rather a new run will be added. For ordering the threads on a "last updated" basis, order by the created_at timestamps of the runs.

Comment thread src/_ravnar/schema/api.py
name: str | None = None
agent_id: str
created_at: datetime
updated_at: datetime
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: add runs as part of the model

Comment thread src/_ravnar/schema/api.py
class AugmentedMessageMixin(BaseModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
created_at: datetime = Field(default_factory=now)
updated_at: datetime | None = None
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Messages are no longer updated, but rather revisioned. This is just internal and the created_at timestamp can be used for ordering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants