Skip to content

prompts.save() is typed to return PromptMetadata, but the actual response is item-shaped (like FileItem) #120

Description

@kryachkow

Name and Version

latest

Summary

Prompts.save() / AsyncPrompts.save() declare a return type of PromptMetadata, but a PUT of a resource returns an item metadata object, not a folder-listing object. This is the same class of bug that was fixed for files.upload() in #118 — the fix there is not yet applied to prompts (and, for consistency, to conversation items).

Current state

PromptMetadata is the folder-listing shape (it carries items and next_token, which are always empty/None on a save() response):

class PromptItem(BaseMetadata):
    updated_at: int
    resource_type: Literal["PROMPT"]


class PromptMetadata(BaseMetadata):
    content_length: int | None = None
    next_token: str | None = None
    items: list[PromptItem] | None
    resource_type: Literal["PROMPT"]

prompts.save() casts the response to PromptMetadata, so:

  • items / next_token are dead fields on every save() result.
  • The fields the server actually returns for an item — etag, createdAt, updatedAt, author — are untyped (they only survive because the models allow extra fields).

ConversationItem has the same limited shape (updated_at only), missing etag / created_at / author that the server returns for listed items.

What is the expected behavior?

In ai-dial-core (com.epam.aidial.core.storage.data) the model hierarchy is:

MetadataBase (abstract)
├── ResourceFolderMetadata   (FOLDER; adds items, nextToken)      ← GET /metadata listing
└── ResourceItemMetadata     (ITEM; adds createdAt, updatedAt, etag, author)
     └── FileMetadata         (adds contentLength, contentType)   ← PUT file upload response

ResourceController.putResource returns ResourceItemMetadata for all resource types (files, prompts, conversations). There is no prompt/conversation-specific subclass — prompts and conversations use the generic ResourceItemMetadata (item) and ResourceFolderMetadata (folder).

So a PUT prompt returns an item with nodeType=ITEM, createdAt/updatedAt/etag/author, and no items/nextToken.

What do you see instead?

Mirror the approach already used for files (where FileItem extends the shared ResourceItemMetadata base introduced in #118):

  1. Make PromptItem and ConversationItem extend ResourceItemMetadata, so they gain properly typed created_at, updated_at, etag, author:

    class PromptItem(ResourceItemMetadata):
        resource_type: Literal["PROMPT"]
    
    class ConversationItem(ResourceItemMetadata):
        resource_type: Literal["CONVERSATION"]
  2. Change Prompts.save() / AsyncPrompts.save() to return PromptItem (cast_to=PromptItem) instead of PromptMetadata.

  3. Keep get_metadata() returning the folder-listing types (PromptMetadata / ConversationMetadata).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions