Type Descriptors#

Let’s explore type-descriptors for a bit.

Many LLMs are somewhat finicky, and a slightly better phrased prompt may help improve results. So if you want to use your own type-descriptions, you can define a custom one and pass it as an argument when creating an extraction chain.

At the moment, Kor only uses a very limited number of internal types. There’s no way to represent a Union or even a Boolean. For the time being use a Text node (or str in pydnatic) to capture more complex / missing types.

import enum
from typing import Optional, List

from kor import from_pydantic
from pydantic import BaseModel, Field

Let’s define a schema#

class Action(enum.Enum):
    play = "play"
    stop = "stop"
    previous = "previous"
    next_ = "next"


class MusicRequest(BaseModel):
    song: Optional[List[str]] = Field(
        description="The song(s) that the user would like to be played."
    )
    album: Optional[List[str]] = Field(
        description="The album(s) that the user would like to be played."
    )
    artist: Optional[List[str]] = Field(
        description="The artist(s) whose music the user would like to hear.",
        examples=[("Songs by paul simon", "paul simon")],
    )
    action: Optional[Action] = Field(
        description="The action that should be taken; one of `play`, `stop`, `next`, `previous`",
        examples=[
            ("Please stop the music", "stop"),
            ("play something", "play"),
            ("play a song", "play"),
            ("next song", "next"),
        ],
    )
    volume: Optional[float] = Field(
        description="Set the volume",
    )
schema, validator = from_pydantic(MusicRequest, description="Music recorder")

TypeScript#

from kor import TypeScriptDescriptor
descriptor = TypeScriptDescriptor()
print(descriptor.describe(schema))
```TypeScript

musicrequest: { // Music recorder
 song: Array<string> // The song(s) that the user would like to be played.
 album: Array<string> // The album(s) that the user would like to be played.
 artist: Array<string> // The artist(s) whose music the user would like to hear.
 action: "play" | "stop" | "previous" | "next" // The action that should be taken; one of `play`, `stop`, `next`, `previous`
 volume: number // Set the volume
}
```

BulletPoint#

from kor import BulletPointDescriptor
descriptor = BulletPointDescriptor()
print(descriptor.describe(schema))
* musicrequest: Object # Music recorder
*  song: Text # The song(s) that the user would like to be played.
*  album: Text # The album(s) that the user would like to be played.
*  artist: Text # The artist(s) whose music the user would like to hear.
*  action: Selection # The action that should be taken; one of `play`, `stop`, `next`, `previous`
*  volume: Number # Set the volume

Custom#

Here’s an example on how to define your own type-description.

from typing import Any
from kor import TypeScriptDescriptor, Object
from kor.nodes import AbstractSchemaNode
class MeowDescriptor(TypeScriptDescriptor):
    def visit_default(self, node: "AbstractSchemaNode", **kwargs: Any) -> List[str]:
        """Default action for a node."""
        depth = kwargs["depth"]
        space = " " + depth * " ~(^._.)" + " "
        return [f"{space}{node.id}: {node.__class__.__name__} # {node.description}"]

    def visit_object(self, node: Object, **kwargs: Any) -> List[str]:
        """Visit an object node."""
        depth = kwargs["depth"]
        code_lines = self.visit_default(node, depth=depth)
        for child in node.attributes:
            code_lines.extend(child.accept(self, depth=depth + 1))
        return code_lines

    def describe(self, node: Object) -> str:
        """Describe the type of the given node."""
        code_lines = node.accept(self, depth=0)
        return "\n".join(code_lines)
print(MeowDescriptor().describe(schema))
  musicrequest: Object # Music recorder
  ~(^._.) song: Text # The song(s) that the user would like to be played.
  ~(^._.) album: Text # The album(s) that the user would like to be played.
  ~(^._.) artist: Text # The artist(s) whose music the user would like to hear.
  ~(^._.) action: Selection # The action that should be taken; one of `play`, `stop`, `next`, `previous`
  ~(^._.) volume: Number # Set the volume