Skip to content

Conversation

@franciscojavierarceo
Copy link
Collaborator

@franciscojavierarceo franciscojavierarceo commented Sep 13, 2025

What does this PR do?

Initial implementation for Conversations and ConversationItems using AuthorizedSqlStore with endpoints to:

  • CREATE
  • UPDATE
  • GET/RETRIEVE/LIST
  • DELETE

Set level=LLAMA_STACK_API_V1.

NOTE: This does not currently incorporate changes for Responses, that'll be done in a subsequent PR.

Closes #3235

Test Plan

  • Unit tests
  • Integration tests

Also comparison of OpenAPI spec for OpenAI API

oasdiff breaking --fail-on ERR docs/static/llama-stack-spec.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/manual_spec/openapi.yaml --strip-prefix-base "/v1/openai/v1" \
--match-path '(^/v1/openai/v1/conversations.*|^/conversations.*)'

Note I still have some uncertainty about this, I borrowed this info from @cdoern on #3514 but need to spend more time to confirm it's working, at the moment it suggests it does.

UPDATE on oasdiff, I investigated the OpenAI spec further and it looks like currently the spec does not list Conversations, so that analysis is useless. Noting for future reference.

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 13, 2025
@franciscojavierarceo franciscojavierarceo force-pushed the conversations-api branch 8 times, most recently from c6844e4 to 03d0116 Compare October 1, 2025 21:03
# Generate item ID based on item type
random_bytes = secrets.token_bytes(24)
item_type = getattr(item, "type", None)
if item_type == "message":
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we'll have to handle other types as they come up.

]
register_schema(ConversationItem, name="ConversationItem")

# Using OpenAI types directly caused issues but some notes for reference:
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

noting this as it was a bit troublesome.

created_items.append(item_dict)

# Get existing items from database
record = await self.sql_store.fetch_one(table="openai_conversations", where={"id": conversation_id})
Copy link
Contributor

Choose a reason for hiding this comment

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

this seems like the wrong semantic. I don't think the API ever says one is appending. a create is a create.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

a create is a create.

Agreed! But this is a create for the /conversations/{conversation_id}/items API so we are adding items to the conversation.

Let me know if I misunderstood you though.

adapter: TypeAdapter[ConversationItem] = TypeAdapter(ConversationItem)
response_items: list[ConversationItem] = [adapter.validate_python(item_dict) for item_dict in created_items]

return ConversationItemList(
Copy link
Contributor

Choose a reason for hiding this comment

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

why are we returning the list again? I think the spec says it returns a Conversation object on create

Copy link
Collaborator Author

@franciscojavierarceo franciscojavierarceo Oct 2, 2025

Choose a reason for hiding this comment

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

Updated based on other comment.

Signed-off-by: Francisco Javier Arceo <[email protected]>
Signed-off-by: Francisco Javier Arceo <[email protected]>
…ls, fixed first/last id, and updated tests

Signed-off-by: Francisco Javier Arceo <[email protected]>
Signed-off-by: Francisco Javier Arceo <[email protected]>
Signed-off-by: Francisco Javier Arceo <[email protected]>
@franciscojavierarceo franciscojavierarceo force-pushed the conversations-api branch 2 times, most recently from a1cdd9a to bfdae80 Compare October 3, 2025 01:36
...

@webmethod(route="/conversations/{conversation_id}/items", method="POST", level=LLAMA_STACK_API_V1)
async def create(self, conversation_id: str, items: list[ConversationItem]) -> ConversationItemList:
Copy link
Contributor

Choose a reason for hiding this comment

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

this method should not be create but add_items or extend

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done.

)

if items:
for item in items:
Copy link
Contributor

Choose a reason for hiding this comment

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

can we insert in batch?

Copy link
Collaborator Author

@franciscojavierarceo franciscojavierarceo Oct 3, 2025

Choose a reason for hiding this comment

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

added!

while our existing implementation of SqlAlchemySqlStoreImpl.insert() supports batch inserts, i did have to update the signature as well as for authorized_sqlstore. I added a test for it.

Signed-off-by: Francisco Javier Arceo <[email protected]>
…pe adjustments and conversations

Signed-off-by: Francisco Javier Arceo <[email protected]>
Copy link
Contributor

@ashwinb ashwinb left a comment

Choose a reason for hiding this comment

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

lgtm, thank you

@ashwinb ashwinb merged commit a20e8ea into llamastack:main Oct 3, 2025
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for OpenAI Conversations

2 participants