Skip to main content

kiarina-agi-data

PyPI Python License

Dependencies

Package Version License
kiarina-agi-base >=2.5.0 MIT
kiarina-agi-file >=2.5.0 MIT
kiarina-utils-common >=2.3.0 MIT
kiarina-utils-file >=2.3.1 MIT
jaxtyping >=0.3.3 MIT
NumPy >=2.0 BSD-3-Clause
Pydantic >=2.11.7 MIT
ulid-py >=1.1.0 Apache-2.0

Installation

pip install kiarina-agi-data

Features

  • Messages and events Manage system, human, AI, and tool messages and streaming chunks as chronological events.
  • Content and file metadata Represent text and files together, estimate tokens, convert to XML, shrink content, and move file data to and from a shared pool.
  • History Keep events, files, tools, and a working memory graph in one state and query or update them by purpose.
  • Memory graphs Represent text, assets, vectors, and metadata as connected memories with permanent or decaying edges.
  • Embeddings Normalize vectors, calculate cosine similarity, and search for the highest-scoring candidates.
  • File bundles Package text and media in a ZIP with a manifest and convert it to and from bytes or a MIME blob.
  • Tool schemas Create tool definitions from Pydantic models or JSON Schema and manage their execution state.

Build a Conversation History

Messages added to History are converted to events. File metadata inside messages is moved to a shared pool to avoid duplication.

from kiarina.agi.history import History
from kiarina.agi.message import AIMessage, HumanMessage

history = History()
history.add_message(HumanMessage.create("What is the weather in Tokyo?"))
history.add_message(AIMessage.create("The forecast is sunny."))

messages = history.get_messages()
assert len(messages) == 2
assert messages[-1].to_text() == "The forecast is sunny."

Search Embeddings

search_embeddings returns results in descending cosine similarity order.

import numpy as np

from kiarina.agi.embedding import Embedding, search_embeddings

candidates = [
    Embedding(kind="document", space_id="example", vector=[1.0, 0.0]),
    Embedding(kind="document", space_id="example", vector=[0.0, 1.0]),
]

results = search_embeddings(np.array([0.9, 0.1]), candidates, top_k=1)
assert results[0].embedding == candidates[0]

Create a File Bundle

from kiarina.agi.file_bundle import FileBundle

bundle = FileBundle.create(
    [
        {"type": "text", "text": "Summary"},
        {
            "type": "image",
            "file_path": "images/chart.png",
            "mime_type": "image/png",
        },
    ],
    files={"images/chart.png": b"PNG data"},
)

restored = FileBundle.from_bytes(bundle.to_bytes())
assert restored.files["images/chart.png"] == b"PNG data"

API Reference

Pydantic model constructors accept the listed fields as keyword arguments. Fields shown with Field(default_factory=...) may be omitted.

kiarina.agi.chat_estimates

from kiarina.agi.chat_estimates import ChatEstimates

class ChatEstimates:
    token_count: int = 0
    file_size: int = 0
    text_file_count: int = 0
    text_token_count: int = 0
    image_file_count: int = 0
    image_token_count: int = 0
    audio_duration: float = 0.0
    audio_file_count: int = 0
    audio_token_count: int = 0
    video_duration: float = 0.0
    video_file_count: int = 0
    video_token_count: int = 0
    pdf_page_count: int = 0
    pdf_file_count: int = 0
    pdf_token_count: int = 0

    @property
    def summary(self) -> str: ...
    @property
    def text(self) -> str: ...
    @property
    def image(self) -> str: ...
    @property
    def audio(self) -> str: ...
    @property
    def video(self) -> str: ...
    @property
    def pdf(self) -> str: ...
    def add_token_count(
        self,
        target: Literal["text", "image", "audio", "video", "pdf"],
        token_count: int,
    ) -> None: ...
    def to_string(self) -> str: ...

kiarina.agi.chat_limits

from kiarina.agi.chat_limits import ChatLimits, ChatLimitsSpecifier

ChatLimitsSpecifier: TypeAlias = str

class ChatLimits:
    token_count_limit: int = 772_000
    file_size_limit: int = 20_000_000
    image_file_count_limit: int = 100
    audio_duration_limit: float = 34_200.0
    audio_file_count_limit: int = 7
    video_duration_limit: float = 3_600.0
    video_file_count_limit: int = 7
    pdf_page_count_limit: int = 100
    pdf_file_count_limit: int = 7

    @property
    def token_count(self) -> str: ...
    @property
    def file_size(self) -> str: ...
    @property
    def image(self) -> str: ...
    @property
    def audio(self) -> str: ...
    @property
    def video(self) -> str: ...
    @property
    def pdf(self) -> str: ...
    def to_string(self) -> str: ...
    @classmethod
    def from_specifier(cls, specifier: ChatLimitsSpecifier) -> Self: ...

kiarina.agi.content

from kiarina.agi.content import Content, dehydrate_content, hydrate_content

def dehydrate_content(
    content: Content,
    pool: FileInfoPool,
) -> tuple[Content, FileInfoPool]: ...

def hydrate_content(
    content: Content,
    pool: FileInfoPool,
) -> tuple[Content, FileInfoPool]: ...

class Content:
    payload: dict[str, Any] | None = None
    text: str = ""
    files: list[FileInfo] = []
    cache_control: dict[str, Any] | None = None
    tag: str = "files"
    description: str = ""
    template: str = "<{tag}{attributes}>\n{inner_xml}\n</{tag}>"
    file_tags: dict[FileType, str] = {}

    @property
    def xml_attributes(self) -> dict[str, Any]: ...
    def to_estimates(self) -> ChatEstimates: ...
    def to_xml(self, inner_xml: str | None = None) -> str: ...
    def to_text(self) -> str: ...

kiarina.agi.display_content

from kiarina.agi.display_content import (
    BaseDisplayContent,
    DisplayContent,
    DisplayContentType,
    FileDisplayContent,
    TextDisplayContent,
)

DisplayContentType = Literal["text", "file"]
DisplayContent: TypeAlias = TextDisplayContent | FileDisplayContent

class BaseDisplayContent:
    type: DisplayContentType
    mime_type: str

class FileDisplayContent(BaseDisplayContent):
    type: Literal["file"] = "file"
    mime_type: str = "application/octet-stream"
    uri_or_file_path: str
    display_name: str | None = None

    @property
    def uri(self) -> str: ...

class TextDisplayContent(BaseDisplayContent):
    type: Literal["text"] = "text"
    mime_type: str = "text/plain"
    text: str
    start_line: int = 1

kiarina.agi.embedding

from kiarina.agi.embedding import (
    Embedding,
    EmbeddingID,
    EmbeddingKind,
    EmbeddingSearchResult,
    EmbeddingSpace,
    EmbeddingSpaceID,
    EmbeddingVector,
    calc_cosine_similarity,
    l2_normalize,
    search_embeddings,
)

EmbeddingID: TypeAlias = str
EmbeddingKind: TypeAlias = str
EmbeddingSpaceID: TypeAlias = str
EmbeddingVector: TypeAlias = Float32[np.ndarray, "dimensions"]

def calc_cosine_similarity(
    x: Embedding | np.ndarray,
    y: Embedding | np.ndarray,
) -> float: ...
def l2_normalize(vector: np.ndarray) -> EmbeddingVector: ...
def search_embeddings(
    query: Embedding | np.ndarray,
    candidates: Iterable[Embedding],
    *,
    top_k: int = 10,
    min_score: float | None = None,
) -> list[EmbeddingSearchResult]: ...

class Embedding:
    id: EmbeddingID = <generated ULID>
    created_at: datetime = <current UTC time>
    kind: EmbeddingKind
    space_id: EmbeddingSpaceID
    vector: list[float]
    metadata: dict[str, Any] = {}

    def to_numpy(self) -> EmbeddingVector: ...
    @classmethod
    def from_numpy(
        cls,
        *,
        kind: EmbeddingKind,
        space_id: EmbeddingSpaceID,
        vector: EmbeddingVector,
        metadata: dict[str, Any] | None = None,
    ) -> Self: ...

class EmbeddingSpace:
    kind: EmbeddingKind
    space_id: EmbeddingSpaceID
    dimension: int
    metadata: dict[str, Any] = {}

class EmbeddingSearchResult:
    embedding: Embedding
    score: float

kiarina.agi.event

from kiarina.agi.event import (
    AIMessageChunkEvent,
    AIMessageEvent,
    BaseEvent,
    CustomEvent,
    Event,
    EventType,
    HumanMessageEvent,
    ToolMessageEvent,
    dehydrate_event,
    dehydrate_events,
    message_to_event,
)

EventType = Literal[
    "human_message", "ai_message", "ai_message_chunk", "tool_message", "custom"
]
Event: TypeAlias = (
    HumanMessageEvent
    | AIMessageEvent
    | AIMessageChunkEvent
    | ToolMessageEvent
    | CustomEvent
)

def dehydrate_event(
    event: Event,
    pool: FileInfoPool,
) -> tuple[Event, FileInfoPool]: ...
def dehydrate_events(
    events: list[Event],
    pool: FileInfoPool,
) -> tuple[list[Event], FileInfoPool]: ...
def message_to_event(message: Message) -> Event: ...

class BaseEvent:
    type: EventType
    id: str = <generated ULID>
    created_at: datetime = <current UTC time>
    transient: bool = False
    hidden: bool = False

    def to_text(self) -> str: ...

class AIMessageChunkEvent(BaseEvent):
    type: Literal["ai_message_chunk"] = "ai_message_chunk"
    transient: bool = True
    message: AIMessageChunk

class AIMessageEvent(BaseEvent):
    type: Literal["ai_message"] = "ai_message"
    message: AIMessage

    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
        tool_calls: list[ToolCall] | None = None,
    ) -> Self: ...

class HumanMessageEvent(BaseEvent):
    type: Literal["human_message"] = "human_message"
    message: HumanMessage

    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
    ) -> Self: ...

class ToolMessageEvent(BaseEvent):
    type: Literal["tool_message"] = "tool_message"
    message: ToolMessage

    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
        *,
        tool_name: str,
        tool_call_args: dict[str, Any] | None = None,
        tool_call_id: str,
    ) -> Self: ...

class CustomEvent(BaseEvent):
    type: Literal["custom"] = "custom"
    payload: dict[str, Any] = {}

    @classmethod
    def create(cls, **kwargs: Any) -> Self: ...

Every concrete event class implements to_text(self) -> str.

kiarina.agi.file_bundle

from kiarina.agi.file_bundle import (
    FileBundle,
    FileBundleContent,
    FileBundleContentInput,
    FileBundleContentVisibility,
    FileBundleFilePath,
    FileBundleManifest,
    FileBundleMediaContent,
    FileBundleMediaContentSpec,
    FileBundleMediaContentType,
    FileBundleTextContent,
    FileBundleTextContentSpec,
)

FileBundleContentVisibility = Literal["always", "supported", "unsupported"]
FileBundleFilePath: TypeAlias = str
FileBundleMediaContentType = Literal["image", "audio", "video", "pdf"]
FileBundleContent: TypeAlias = FileBundleMediaContent | FileBundleTextContent
FileBundleContentInput: TypeAlias = (
    str
    | FileBundleTextContentSpec
    | FileBundleMediaContentSpec
    | FileBundleContent
)

class FileBundleTextContentSpec(TypedDict):
    type: Literal["text"]
    text: str
    visibility: NotRequired[FileBundleContentVisibility]

class FileBundleMediaContentSpec(TypedDict):
    type: FileBundleMediaContentType
    file_path: FileBundleFilePath
    mime_type: str
    visibility: NotRequired[FileBundleContentVisibility]
    prefix_text: NotRequired[str | None]

class FileBundleTextContent:
    type: Literal["text"] = "text"
    text: str
    visibility: FileBundleContentVisibility = "always"

class FileBundleMediaContent:
    type: FileBundleMediaContentType
    file_path: FileBundleFilePath
    mime_type: str
    visibility: FileBundleContentVisibility = "always"
    prefix_text: str | None = None

class FileBundleManifest:
    FILE_NAME: ClassVar[str] = "manifest.json"
    contents: list[FileBundleContent] = []

    @classmethod
    def create(
        cls,
        contents: list[FileBundleContentInput],
    ) -> Self: ...

@dataclass
class FileBundle:
    manifest: FileBundleManifest = FileBundleManifest()
    files: dict[FileBundleFilePath, bytes] = {}
    MIME_TYPE: ClassVar[str] = "application/zip"

    def to_bytes(self) -> bytes: ...
    def to_mime_blob(self) -> MIMEBlob: ...
    @classmethod
    def from_bytes(cls, data: bytes) -> Self: ...
    @classmethod
    def from_mime_blob(cls, blob: MIMEBlob) -> Self: ...
    @classmethod
    def create(
        cls,
        manifest_contents: list[FileBundleContentInput],
        files: dict[FileBundleFilePath, bytes] | None = None,
    ) -> Self: ...

FileBundle instances can be merged with +. A duplicate file path, a missing file referenced by the manifest, or an unsafe ZIP path raises ValueError.

kiarina.agi.file_info

from kiarina.agi.file_info import (
    AudioFileInfo,
    BaseFileInfo,
    FileID,
    FileInfo,
    FileType,
    Group,
    ImageFileInfo,
    OtherFileInfo,
    PDFFileInfo,
    TextFileInfo,
    UniqueKey,
    VideoFileInfo,
    deduplicate_file_infos,
    detect_file_type,
    shrink_file_infos,
)

FileID: TypeAlias = str
Group: TypeAlias = str
UniqueKey: TypeAlias = str
FileType = Literal["text", "image", "audio", "video", "pdf", "other"]
FileInfo: TypeAlias = (
    TextFileInfo
    | ImageFileInfo
    | AudioFileInfo
    | VideoFileInfo
    | PDFFileInfo
    | OtherFileInfo
)

def deduplicate_file_infos(file_infos: list[FileInfo]) -> list[FileInfo]: ...
def detect_file_type(file_blob: FileBlob) -> FileType: ...
def shrink_file_infos(
    file_infos: list[FileInfo],
    *,
    reduce: TokenCount,
    reserve: TokenCount = 0,
) -> tuple[list[FileInfo], TokenCount]: ...

class BaseFileInfo:
    type: FileType
    id: FileID = <generated ULID>
    created_at: datetime = <current UTC time>
    node_id: str | None = None
    mime_type: str
    file_hash: str
    file_size: int
    token_count: TokenCount
    intermediate_file_path: str | None
    asset_uri: str | None
    uri_or_file_path: URIOrFilePath
    name: str = ""
    description: str = ""
    pinned: bool = False
    inline: bool = False
    metadata_only: bool = False
    content_only: bool = False
    no_merge: bool = False
    group: Group | None = None
    unique_key: UniqueKey | None = None
    keep_from_end: bool = False
    tag: str = "file"
    default_template: str = "<{tag}{attributes} />"
    metadata_only_template: str = '<{tag}{attributes} metadata_only="True" />'

    @property
    def is_uri(self) -> bool: ...
    @property
    def uri(self) -> str: ...
    @property
    def prepared(self) -> bool: ...
    @property
    def xml_attributes(self) -> dict[str, Any]: ...
    @property
    def optional_export_fields(self) -> tuple[str, ...]: ...
    def export(self) -> dict[str, Any]: ...
    def to_estimates(self) -> ChatEstimates: ...
    def to_metadata_estimates(self) -> ChatEstimates: ...
    def to_content_estimates(self) -> ChatEstimates: ...
    def to_xml(self, tag: str | None = None) -> str: ...
    def to_metadata_only_xml(self, tag: str | None = None) -> str: ...
    def as_metadata_only(self) -> Self: ...
    def shrink(
        self,
        reduce: TokenCount,
        reserve: TokenCount = 0,
    ) -> tuple[Self, TokenCount]: ...
    def get_value(self, field_name: str, default: Any = None) -> Any: ...

Concrete classes add the following fields and properties.

class TextFileInfo(BaseFileInfo):
    type: Literal["text"] = "text"
    start_line: int = 1
    end_line: int = -1
    line_count: int
    raw_text: str | None

    @property
    def normalized_start_line(self) -> int: ...
    @property
    def normalized_end_line(self) -> int: ...
    @property
    def segment_line_count(self) -> int: ...
    def shrink_by_line(self, keep_line_count: int) -> Self: ...

class ImageFileInfo(BaseFileInfo):
    type: Literal["image"] = "image"
    width: int
    height: int

class AudioFileInfo(BaseFileInfo):
    type: Literal["audio"] = "audio"
    start_time: float = 0.0
    end_time: float = -1.0
    duration: float

    @property
    def normalized_start_time(self) -> float: ...
    @property
    def normalized_end_time(self) -> float: ...
    @property
    def segment_duration(self) -> float: ...

class VideoFileInfo(BaseFileInfo):
    type: Literal["video"] = "video"
    start_time: float = 0.0
    end_time: float = -1.0
    width: int
    height: int
    fps: float
    analysis_fps: float = 1.0
    duration: float

    @property
    def normalized_start_time(self) -> float: ...
    @property
    def normalized_end_time(self) -> float: ...
    @property
    def segment_duration(self) -> float: ...

class PDFFileInfo(BaseFileInfo):
    type: Literal["pdf"] = "pdf"
    start_page: int = 1
    end_page: int = -1
    page_count: int
    analysis_dpi: int = 144

    @property
    def normalized_start_page(self) -> int: ...
    @property
    def normalized_end_page(self) -> int: ...
    @property
    def segment_page_count(self) -> int: ...

class OtherFileInfo(BaseFileInfo):
    type: Literal["other"] = "other"

Concrete classes also implement content-specific xml_attributes, optional_export_fields, and to_content_estimates().

kiarina.agi.file_info_pool

from kiarina.agi.file_info_pool import (
    FileInfoPool,
    dehydrate_file_infos,
    find_file_index,
    hydrate_file_infos,
)

FileInfoPool: TypeAlias = list[FileInfo]

def dehydrate_file_infos(
    file_infos: list[FileInfo],
    pool: FileInfoPool,
) -> tuple[list[FileInfo], FileInfoPool]: ...
def find_file_index(pool: FileInfoPool, file_id: FileID) -> int | None: ...
def hydrate_file_infos(
    file_infos: list[FileInfo],
    pool: FileInfoPool,
) -> tuple[list[FileInfo], FileInfoPool]: ...

kiarina.agi.history

from kiarina.agi.history import History

class History:
    events: list[Event] = []
    file_infos: FileInfoPool = []
    tool_infos: list[ToolInfo] = []
    memory_graph: MemoryGraph = MemoryGraph()
    metadata: dict[str, Any] = {}

    def clear(self) -> None: ...
    def get_last_event(self, event_type: EventType) -> Event | None: ...
    def get_pending_tool_calls(self) -> list[ToolCall]: ...
    def add_event(self, event: Event) -> None: ...
    def replace_event(self, target: Event, replacement: Event) -> None: ...
    def get_last_message(self, message_type: MessageType) -> Message | None: ...
    def get_messages(self) -> list[Message]: ...
    def add_message(self, message: Message) -> None: ...
    def get_file_info(self, *, unique_key: UniqueKey) -> FileInfo | None: ...
    def get_file_infos(
        self,
        *,
        uri_or_file_path: URIOrFilePath | None = None,
        group: Group | None = None,
        no_group: bool = False,
        no_unique_key: bool = False,
        ignore_unique_keys: list[UniqueKey] | None = None,
        in_message: bool | None = None,
    ) -> list[FileInfo]: ...
    def add_file_info(self, file_info: FileInfo) -> None: ...
    def remove_file_info(self, file_id: FileID) -> None: ...
    def get_tool_info(self, name: ToolName) -> ToolInfo | None: ...
    def get_tool_infos(
        self,
        *,
        state: ToolState | None = None,
    ) -> list[ToolInfo]: ...
    def add_tool_info(self, tool_info: ToolInfo) -> None: ...
    def remove_tool_info(self, name: ToolName) -> None: ...

kiarina.agi.memory

from kiarina.agi.memory import Memory, MemoryID, MemoryType

MemoryID: TypeAlias = str
MemoryType: TypeAlias = str

class Memory:
    id: MemoryID = <generated ULID>
    type: MemoryType
    version: int = 1
    text: str = ""
    asset_uri: URIOrFilePath | None = None
    vector: list[float] | None = None
    edit_protected: bool = False
    delete_protected: bool = False
    activated_at: datetime = <current UTC time>
    metadata: dict[str, Any] = {}

kiarina.agi.memory_graph

from kiarina.agi.memory_graph import DecayTime, MemoryGraph

DecayTime: TypeAlias = float

class MemoryGraph:
    nodes: dict[MemoryID, Memory] = {}
    edges: dict[MemoryID, dict[MemoryID, DecayTime]] = {}

    def clear(self) -> None: ...
    def count(self) -> int: ...
    def get(self, id: MemoryID) -> Memory | None: ...
    def mget(self, ids: list[MemoryID]) -> list[Memory]: ...
    def set(self, memory: Memory) -> None: ...
    def mset(self, memories: list[Memory]) -> None: ...
    def delete(self, id: MemoryID) -> None: ...
    def connect(
        self,
        source_id: MemoryID,
        target_id: MemoryID,
        *,
        bidirectional: bool = True,
        remaining_time: float = 0,
    ) -> None: ...
    def disconnect(
        self,
        source_id: MemoryID,
        target_id: MemoryID,
        *,
        bidirectional: bool = True,
    ) -> None: ...
    def forget(
        self,
        source_id: MemoryID,
        target_id: MemoryID,
        *,
        bidirectional: bool = True,
        acceleration_time: float = 0,
    ) -> None: ...
    def find_adjacent_ids(
        self,
        id: MemoryID,
        *,
        depth: int = 1,
        memory_type: MemoryType | None = None,
        offset: int = 0,
        limit: int = 0,
    ) -> list[MemoryID]: ...

kiarina.agi.message

from kiarina.agi.message import (
    AIMessage,
    AIMessageChunk,
    BaseMessage,
    HumanMessage,
    Message,
    MessageType,
    SystemMessage,
    ToolCall,
    ToolCallChunk,
    ToolMessage,
    dehydrate_message,
    hydrate_messages,
)

MessageType = Literal["system", "human", "ai", "ai_chunk", "tool"]
Message: TypeAlias = (
    SystemMessage | HumanMessage | AIMessage | AIMessageChunk | ToolMessage
)

def dehydrate_message(
    message: Message,
    pool: FileInfoPool,
) -> tuple[Message, FileInfoPool]: ...
def hydrate_messages(
    messages: list[Message],
    pool: FileInfoPool,
) -> tuple[list[Message], FileInfoPool]: ...

class BaseMessage:
    type: MessageType
    contents: list[Content] = []
    metadata: dict[str, Any] = {}  # free data, never sent to a model

    def get_file_infos(self) -> list[FileInfo]: ...
    def contents_to_text(self) -> str: ...
    def to_estimates(self) -> ChatEstimates: ...
    def to_text(self) -> str: ...
    def replace_content(self, old: Content, new: Content) -> Self: ...
    def shrink(
        self,
        pool: FileInfoPool,
        reduce: TokenCount,
        reserve: TokenCount = 0,
    ) -> tuple[FileInfoPool, TokenCount]: ...

class SystemMessage(BaseMessage):
    type: Literal["system"] = "system"
    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
    ) -> Self: ...

class HumanMessage(BaseMessage):
    type: Literal["human"] = "human"
    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
    ) -> Self: ...

class AIMessage(BaseMessage):
    type: Literal["ai"] = "ai"
    tool_calls: list[ToolCall] = []
    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
        *,
        tool_calls: list[ToolCall] | None = None,
    ) -> Self: ...

class AIMessageChunk(AIMessage):
    type: Literal["ai_chunk"] = "ai_chunk"
    tool_call_chunks: list[ToolCallChunk] = []

class ToolMessage(BaseMessage):
    type: Literal["tool"] = "tool"
    tool_name: str
    tool_call_args: dict[str, Any] = {}
    tool_call_id: str
    return_direct: bool = False
    failed: bool = False
    artifact: dict[str, Any] = {}
    display_contents: list[DisplayContent] = []

    @classmethod
    def create(
        cls,
        text: str = "",
        files: list[FileInfo] | None = None,
        *,
        tool_name: str,
        tool_call_args: dict[str, Any] | None = None,
        tool_call_id: str,
    ) -> Self: ...

class ToolCall:
    id: str = <generated ULID>
    name: str
    args: dict[str, Any] = {}

    def to_estimates(self) -> ChatEstimates: ...
    def to_text(self) -> str: ...

class ToolCallChunk:
    id: str | None = None
    name: str | None = None
    args: str | None = None
    index: int | None = None

kiarina.agi.tool_info

from kiarina.agi.tool_info import (
    ToolChoice,
    ToolInfo,
    ToolName,
    ToolState,
    create_tool_info,
)

ToolName: TypeAlias = str
ToolChoice: TypeAlias = Literal["auto", "any"] | ToolName
ToolState = Literal["active", "inactive", "disabled"]

def create_tool_info(
    source: type[BaseModel] | dict[str, Any],
    name: ToolName | None = None,
    description: str | None = None,
    cache_control: dict[str, Any] | None = None,
) -> ToolInfo: ...

class ToolInfo:
    name: ToolName
    description: str
    args_schema: dict[str, Any] = {}
    cache_control: dict[str, Any] | None = None
    state: ToolState = "active"

    def to_estimates(self) -> ChatEstimates: ...
    def to_json_schema(self) -> dict[str, Any]: ...

Metadata

Release files for kiarina-agi-data 2.36.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kiarina-agi-data 2.36.0
File Size Uploaded
kiarina_agi_data-2.36.0.tar.gz 40.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kiarina-agi-data 2.36.0
File Interpreter ABI Platform
kiarina_agi_data-2.36.0-py3-none-any.whl Python 3 none any Details

Total release size: 99.0 kB

Release files / kiarina_agi_data-2.36.0.tar.gz

Download URL kiarina_agi_data-2.36.0.tar.gz
Size 40.0 kB
Tags Source
SHA-256 checksum
How to use checksums
49c6044db679d629676c5ce7997c53d5cd56f3e28d887c7bc632b96cb5c799a8
BLAKE2b-256 checksum
How to use checksums
c9c0506ae7bb0572c443880da72aec59ee1137d1e8b4365890454269bcb07e27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / kiarina_agi_data-2.36.0-py3-none-any.whl

Download URL kiarina_agi_data-2.36.0-py3-none-any.whl
Size 59.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9a865a36751a678f69978efd858fc61aadbb15dd96802856e7eca3f5c8857d21
BLAKE2b-256 checksum
How to use checksums
e39ed7b40c8e4e0d7be5b95632d22d1ba9bfdd0732fa07217693daed0def507a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.36.0 This release

2 release files

2.34.0

2 release files

2.31.0

2 release files

2.19.0

2 release files

2.7.0

2 release files

2.6.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page