Skip to main content

Annotations & Fragments

Given a file or entity, what annotations, fragments, and fields will the pipeline produce?
This guide is for consumers of pipeline output — developers querying entities from OpenSearch, building UIs on top of annotations, or integrating downstream systems. It documents the contract: what you can expect on an entity after processing, by input type.


Table of Contents​

  • Quick Start: What Happens to My File?
  • Entity Structure (Output Shape)
  • Output by Input Type
    • Documents
    • Images
    • Audio
    • Video
    • Generic / Other
  • Annotation Dictionary
  • Fragment Dictionary
  • Shared Data Formats
  • Cheat Sheet

Quick Start: What Happens to My File?​

You upload a file
│
▼
┌──────────────────────────────────────────────────┐
│ The pipeline inspects os_item_content_type │
│ (MIME type) and routes accordingly: │
│ │
│ application/pdf ──────────► Document path │
│ application/vnd.*office*──► Document path │
│ application/vnd.*present*─► Document path │
│ application/msword ───────► Document path │
│ image/* ──────────────────► Image path │
│ audio/* ──────────────────► Audio path │
│ video/* ──────────────────► Video path │
│ text/csv ─────────────────► Spreadsheet path │
│ application/vnd.ms-excel──► Spreadsheet path │
│ application/vnd.*sheet*───► Spreadsheet path │
│ application/vnd.*ods──────► Spreadsheet path │
│ text/tab-separated-values─► Spreadsheet path │
└──────────────────────────────────────────────────┘
│
▼
Entity comes back with:
• annotations (text, tags, NER, summary, embeddings…)
• fragments (pages, keyframes, audio segments…)
• each fragment also carries its own annotations

Entity Structure in OpenSearch​

After processing, entities are indexed into OpenSearch. The document _id equals the entity's os_entity_uid. Fields marked with ◆ are always present; ◇ are conditional.

Document Shape​

OpenSearch document (_id = os_entity_uid)
│
├── document_fields # Ontology record fields (flat dict)
│ ├── os_entity_uid ◆ # Unique identifier (= _id = entity_id)
│ ├── entity_id ◆ # Same as os_entity_uid
│ ├── entity_type ◆ # Ontology type (e.g. "os_document", "os_fragment")
│ ├── os_concept ◆ # Same as entity_type
│ ├── entity_label ◆ # Human-readable name
│ ├── os_workspace ◆ # Workspace ID
│ ├── os_item_content_type ◆ # MIME type
│ ├── os_has_attachment ◆ # true if binary content exists
│ ├── os_parent_folder ◇ # Parent folder UID (for files)
│ ├── source_entity_uid ◇ # Root entity UID — same for ALL fragments of a file
│ ├── os_parent_uid ◇ # Immediate parent UID — for tree reconstruction
│ ├── fragment_index ◇ # 0-based position among siblings (under same parent)
│ ├── fragment_count ◇ # Total sibling count
│ ├── fragment_collection_type ◇ # Fragment category (e.g. "document_pages")
│ └── ... (any ontology-specific fields)
│
├── annotations # Enrichment data from pipeline
│ ├── extract:txt ◇ # Extracted / transcribed text
│ ├── extract:txtLang ◇ # Language of extracted text
│ ├── extract:metadata ◇ # File metadata (ExifTool)
│ ├── summary:txt ◇ # LLM summary
│ ├── ner:entities ◇ # Named entities
│ ├── image:annotations ◇ # Image tags & detections
│ ├── rag:chunks ◇ # RAG text chunks + embeddings
│ ├── rag:fulltext ◇ # Concatenated RAG text
│ └── materialized ◇ # Rolled-up child fragment data
│ ├── ner:entities ◇
│ └── ...
│
└── processing_status # Pipeline status
├── status_code ◆ # RUNNING | COMPLETED | FAILED
├── reason ◆ # Status description
└── timestamp ◆ # When status was set

source_entity_uid vs os_parent_uid​

These two fields serve different purposes and it is important to understand the distinction:

FieldPoints ToSame Across Tree?Purpose
source_entity_uidThe root file/entity that was splitYes — identical on every fragment in the treeFlat lookup: "give me all fragments of this file"
os_parent_uidThe immediate parent (root entity or another fragment)No — varies per tree levelTree reconstruction: "who is my direct parent?"
┌───────────────────┐
│ Root File │
│ _id = "file-001" │
└────────┬──────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Page 1 │ │ Page 2 │ │ Page 3 │
│ │ │ │ │ │
│ source_ │ │ source_ │ │ source_ │
│ entity_ │ │ entity_ │ │ entity_ │
│ uid = │ │ uid = │ │ uid = │
│ file-001 │ │ file-001 │ │ file-001 │ ← all same: root file
│ │ │ │ │ │
│ os_ │ │ os_ │ │ os_ │
│ parent_ │ │ parent_ │ │ parent_ │
│ uid = │ │ uid = │ │ uid = │
│ file-001 │ │ file-001 │ │ file-001 │ ← parent is root file
└────┬─────┘ └──────────┘ └──────────┘
│
┌────┴────────┐
▼ ▼
┌────────┐ ┌────────┐
│ Img A │ │ Img B │
│ │ │ │
│source_ │ │source_ │
│entity_ │ │entity_ │
│uid = │ │uid = │
│file-001│ │file-001│ ← still the root file
│ │ │ │
│os_ │ │os_ │
│parent_ │ │parent_ │
│uid = │ │uid = │
│page-1 │ │page-1 │ ← parent is Page 1 (not root)
└────────┘ └────────┘

Querying Annotations​

In python using the octostar-python-client library, use get_entity_annotations() to fetch annotations for entities. The function supports automatic fragment fetching and merging via the recurse and merge parameters:

from octostar.utils.search import get_entity_annotations

# Parent annotations only (no fragments)
result = get_entity_annotations.sync(
os_entity_uids=["uid-1", "uid-2"],
recurse=False,
client=client,
)
# {"uid-1": {"extract:txt": "...", ...}, "uid-2": {...}}

# Parent + fragment annotations merged together (default)
result = get_entity_annotations.sync(
os_entity_uids=["uid-1"],
recurse=True, # fetch fragments via source_entity_uid
merge=True, # merge fragment annotations into parent
client=client,
)
# {"uid-1": {"extract:txt": "full merged text...", ...}}

# Parent + fragment annotations kept separate, in DFS tree order
result = get_entity_annotations.sync(
os_entity_uids=["uid-1"],
recurse=True,
merge=False, # return each fragment's annotations separately
client=client,
)
# {"uid-1": {"uid-1": {...parent...}, "frag-1": {...}, "frag-2": {...}, ...}}

# Fetch specific fields only
result = get_entity_annotations.sync(
os_entity_uids=["uid-1"],
fields=["extract:txt", "ner:entities"],
client=client,
)

When recurse=True, the function internally:

  1. Queries parent annotations by _id
  2. Queries all fragments by source_entity_uid (flat fetch — gets the entire tree at once)
  3. Rebuilds the tree using os_parent_uid for correct DFS ordering
  4. Merges (or returns) annotations in tree order

Merge strategies used when merge=True:

Annotation KeyStrategyBehavior
extract:txtstrconcatConcatenate with \n
rag:fulltextstrconcatConcatenate with \n
image:annotationslstconcatConcatenate lists
image:annotations-keylstconcatConcatenate lists
image:annotations-sensitivelstconcatConcatenate lists
image:annotations-settingslstconcatConcatenate lists
ner:entitieslstconcatConcatenate lists
rag:chunkslstconcatConcatenate lists
summary:txtfirstKeep first (parent) value
extract:metadatafirstKeep first (parent) value
(everything else)firstKeep first non-null value

Querying Fragments Directly​

Get all fragments of a file (flat)​

Use source_entity_uid to find every fragment that belongs to a root file, regardless of tree depth — this returns a flat list:

{
"query": {
"bool": {
"must": [
{"term": {"document_fields.os_workspace.keyword": "<workspace_id>"}},
{"term": {"document_fields.source_entity_uid.keyword": "<root_file_uid>"}}
]
}
},
"size": 10000,
"sort": [{"document_fields.fragment_index": {"order": "asc"}}],
"_source": ["document_fields", "annotations"]
}

This returns pages, images embedded in those pages, audio tracks, etc. — all in one query.

Timbr SQL equivalent:

SELECT entity_id, entity_type, entity_label, fragment_index,
fragment_collection_type, os_parent_uid
FROM timbr.`os_fragment`
WHERE os_workspace = :workspace_id
AND source_entity_uid = :root_file_uid

Reconstruct the tree​

Once you have the flat list, use os_parent_uid to build the parent-child hierarchy:

  1. Every fragment whose os_parent_uid = <root_file_uid> is a direct child of the root (e.g. pages)
  2. Every fragment whose os_parent_uid = <page_fragment_uid> is a child of that page (e.g. extracted images)
  3. Sort children at each level by fragment_index
# Pseudocode: build tree from flat fragment list
root_id = "file-001"
children_by_parent = defaultdict(list)

for frag in all_fragments:
children_by_parent[frag["os_parent_uid"]].append(frag)

for kids in children_by_parent.values():
kids.sort(key=lambda f: f["fragment_index"])

# children_by_parent[root_id] → [Page 1, Page 2, Page 3]
# children_by_parent["page-1-uid"] → [Image A, Image B]

Get only direct children of a specific node​

To get just one level (e.g. only pages of the root, or only images of page 1), filter by os_parent_uid:

{
"query": {
"bool": {
"must": [
{"term": {"document_fields.os_workspace.keyword": "<workspace_id>"}},
{"term": {"document_fields.os_parent_uid.keyword": "<parent_node_uid>"}}
]
}
},
"sort": [{"document_fields.fragment_index": {"order": "asc"}}],
"_source": ["document_fields", "annotations"]
}

Fragment Hierarchy Diagram​

┌──────────────────────────────────────────────────────────────────────┐
│ Root File │
│ _id = "file-001" │
│ entity_type = "os_file" │
└───────────────────────────────┬──────────────────────────────────────┘
│
All fragments below have source_entity_uid = "file-001"
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Page Frag 1 │ │ Page Frag 2 │ │ Page Frag 3 │
│ _id="pg-1" │ │ _id="pg-2" │ │ _id="pg-3" │
│ │ │ │ │ │
│ os_parent_uid │ │ os_parent_uid │ │ os_parent_uid │
│ = "file-001" │ │ = "file-001" │ │ = "file-001" │
│ fragment_idx=0│ │ fragment_idx=1│ │ fragment_idx=2│
│ collection_ │ │ collection_ │ │ collection_ │
│ type= │ │ type= │ │ type= │
│ "document_ │ │ "document_ │ │ "document_ │
│ pages" │ │ pages" │ │ pages" │
└───────┬───────┘ └───────────────┘ └───────────────┘
│
│ Children of Page 1 (os_parent_uid = "pg-1")
│
┌────┴──────────┐
▼ ▼
┌───────────┐ ┌───────────┐
│ Image A │ │ Image B │
│ _id= │ │ _id= │
│ "img-a" │ │ "img-b" │
│ │ │ │
│os_parent_ │ │os_parent_ │
│uid="pg-1" │ │uid="pg-1" │ ← immediate parent is page, not root
│ │ │ │
│source_ │ │source_ │
│entity_uid │ │entity_uid │
│="file-001"│ │="file-001"│ ← root is still the original file
│ │ │ │
│collection_│ │collection_│
│type= │ │type= │
│"document_ │ │"document_ │
│ images" │ │ images" │
└───────────┘ └───────────┘

Summary: Query by source_entity_uid to get all fragments of a file in one flat query. Use os_parent_uid to reconstruct the tree. Use os_parent_uid to query only direct children of a specific node.

Missing fragments: If a fragment failed to process or was not indexed, tree traversal via os_parent_uid may hit a dead end — children of the missing fragment become unreachable because their parent node is absent. A source_entity_uid query is resilient to this: it always returns every indexed fragment regardless of gaps in the tree, so you can still read annotations from all surviving fragments even if the hierarchy is incomplete. Prefer source_entity_uid when completeness matters more than tree structure.


Output by Input Type​

Documents​

Applies to: application/pdf, application/vnd.openxmlformats-officedocument.*, application/msword, application/vnd.oasis.opendocument.*, and other Tika-supported MIME types.

Splitting Behavior by MIME Type​

Not all document types are split the same way. Splitting depends on whether a splitter plugin exists for the MIME type and what unit it operates on, as well as splitting parameters (max_pages, max_rows, extract_images):

MIME TypeSplit UnitSplitting Behavior
application/pdfpageNative PDF page extraction
application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/mswordpageConverted to PDF via LibreOffice, then page-split
application/vnd.oasis.opendocument.textpageConverted to PDF via LibreOffice, then page-split
application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.ms-powerpointslideConverted to PDF, each slide becomes a page
application/vnd.oasis.opendocument.presentationslideSame as above
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excelrowChunked by data rows (controlled by max_rows, not max_pages)
text/csv, text/tab-separated-valuesrowSame row-based chunking
application/vnd.oasis.opendocument.spreadsheetrowSame row-based chunking
text/plain and other types—No splitter plugin. Text is extracted as a single unit, no page/row fragments are produced.

Key: max_pages only affects page/slide-based types. max_rows only affects row-based types. If neither limit applies to a given MIME type, the file passes through as a single entity with no fragments.

Annotations on the Parent Entity​

AnnotationTypePresenceDescription
extract:txtstrSometimesFull extracted text (Tika parser; OCR fallback for scanned PDFs); only present if document has not been split
extract:txtLangstrSometimes (when text is non-empty)Detected language of extracted text; only present if document has not been split
extract:metadatadictAlwaysExifTool file metadata. Keys vary per format (see extract:metadata).
ner:entitiesdictUsuallyNamed entities extracted from summary. Structure: { label: [value, ...] }
summary:txtstrAlways for PDF, DOCX, DOC, ODT. Not produced for PPTX, XLSX, CSV, and others.LLM-generated summary; Hierarchical when the document has fragments.
extract:frontmatterdictOptionalDocument front-matter — keys: toc, abstract, glossary, introduction
rag:chunkslist[dict]AlwaysRAG text chunks with embeddings (see RAG Chunks)
rag:fulltextstrUsuallyAll RAG chunk texts concatenated
materialized.ner:entitiesWhen fragmentedChild annotations accumulated on parent

summary:txt MIME allowlist: By default, only application/pdf, DOCX (application/vnd.openxmlformats-officedocument.wordprocessingml.document), DOC (application/msword), and ODT (application/vnd.oasis.opendocument.text) are eligible for summarization. Presentations, spreadsheets, CSV, and plain text are not summarized.

Fragments Produced​

Collection TypeContentWhen ProducedRecord Fields
document_pagesOne entity per page or slidePage/slide-based types (PDF, DOCX, DOC, ODT, PPTX, PPT, ODP) when max_pages is setfragment_page_number, fragment_start, fragment_end, fragment_index, fragment_count
document_page_groupsGroups of consecutive pages (e.g. pages 1–20, 21–40)When the document has more pages than max_pages — individual pages are grouped under an intermediate nodeSame as above
table_rowsOne entity per row rangeRow-based types (XLSX, XLS, CSV, TSV, ODS) when max_rows is setfragment_start, fragment_end, fragment_index, fragment_count
table_row_groupsGroups of consecutive row rangesWhen the spreadsheet has more rows than max_rows and multiple grouping levels applySame as above
document_imagesEmbedded images extracted from the documentWhen extract_images is enabled (applies to page-based and spreadsheet types)fragment_index, fragment_count, os_item_content_type: "image/*"

Row-based types (XLSX, XLS, CSV, TSV, ODS) produce table_rows fragments (or table_row_groups when grouping) when max_rows is set. Each fragment represents a row range — fragment_start/fragment_end refer to row indices.

Types without a splitter plugin (text/plain, etc.) produce no fragments — only the parent entity is enriched.

Annotations on the main document​

AnnotationPresenceNotes
extract:txtNoSee the individual pages
extract:txtLangNoSee the individual pages
ner:entitiesUsuallyNER for the document summary
materialized.ner:entitiesUsuallyNER for the whole document
summary:txtAlwaysLLM summary of the entire document

Annotations on document_page_groups Fragments​

AnnotationPresenceNotes
extract:txtNoSee the individual pages
extract:txtLangNoSee the individual pages
ner:entitiesUsuallyNER for the group summary
materialized.ner:entitiesUsuallyNER for all children pages
summary:txtAlwaysLLM summary of the group

Annotations on document_pages (Leaf) Fragments​

AnnotationPresenceNotes
extract:txtAlwaysText of that individual page/slide/row-range
extract:txtLangAlways (if text)Text language
ner:entitiesUsuallyNER for the page's text
summary:txtSometimesOnly produced if the page has sub-fragments (e.g. images). Summary of the page contents
section:typeAlwaysOne of: textual, image, tabular, list, mixed

summary:txt on fragments: The parent entity and document_page_groups are prioritized for LLM summarization budget. Individual document_pages leaves only get summary:txt when the remaining LLM call budget (governed by max_llm_calls) allows it. For large documents with many pages, most leaf pages will not have summary:txt.

Annotations on image fragments (extracted document images): Same as Images below.


Images​

Applies to: image/jpeg, image/png, image/gif, image/webp, image/tiff, image/bmp, image/heic, and other image MIME types.

Annotations on the Entity​

AnnotationTypePresenceDescription
extract:txtstrAlwaysTwo-paragraph description: concise + detailed, generated by vision LLM
extract:txtLangstrAlwaysAlways "english" (LLM output language)
extract:metadatadictAlwaysExifTool metadata (EXIF, XMP, IPTC — varies by image format)
image:annotationslist[dict]AlwaysAll detected labels. Each: {"label": "..."}. Does not include face embeddings (they exist as separate fragments)
image:annotations-keylist[dict]AlwaysInvestigation-relevant labels (e.g. firearms, cash)
image:annotations-sensitivelist[dict]Always (may be empty list)Sensitive content flags (e.g. nudity_pornography, violence)
image:annotations-settinglist[dict]AlwaysImage general setting labels (e.g. Photo, Indoor, Morning)
ner:entitiesdictUsuallyNamed entities from the image description
rag:chunkslist[dict]AlwaysRAG chunks from description text and image annotations
rag:fulltextstrAlwaysConcatenated RAG text

Fragments Produced​

Collection TypeContentPresenceRecord Fields
face_cropsCropped face regions as separate image entitiesWhen multiple faces detected (or single face covering < 70% of image area)fragment_index, fragment_count, fragment_image_bbox

Annotations on face crop fragments:

AnnotationPresenceNotes
image:annotationsAlwaysSingle detection: {"label": "face", "bbox": [...], "confidence": ..., "embedding": {...}}

Note: When exactly one face is detected and it covers ≥ 70% of the image area, no face crop fragment is created — the detection is written directly onto the parent entity's image:annotations.

Possible image:annotations Label Values​

Labels come from a structured analysis model. These are the possible values:

Image type: Drawing, Photo, Screenshot, Scan, Security Camera Footage, Satellite Image

Setting: Indoor, Outdoor, plus a free-form category string

Conditions: Morning, Noon, Afternoon, Evening, Night, Sunny, Cloudy, Rainy, Snowy, Foggy, Spring, Summer, Autumn, Winter

Object detection (boolean flags): cars, motorcycles, trucks, planes, helicopters, boats, flags, drugs_pills, drugs_powder, drugs_other, credit_cards, id_cards, other_cards, luxury_items, cash, alcohol, tattoos, firearms, blood_blood_stains, plus free-form entries in other_objects

Sensitive categories (boolean flags): nudity_pornography, violence, terrorism, war, body_injury


Audio​

Applies to: audio/mpeg, audio/wav, audio/ogg, audio/flac, audio/aac, and other audio MIME types.

Annotations on the Parent Entity​

AnnotationTypePresenceDescription
extract:txtstrSometimesFull transcript, if the audio has not been split
extract:txtLangstrSometimesDetected language of transcript, if the audio has not been split
extract:metadatadictAlwaysExifTool audio metadata (duration, bitrate, channels, etc.)
ner:entitiesdictUsuallyNamed entities from transcript text
rag:chunkslist[dict]UsuallyRAG chunks from transcript
rag:fulltextstrUsuallyConcatenated RAG text

Fragments Produced​

Collection TypeContentPresenceRecord Fields
audio_splitTime-based or size-based audio segmentsAlwaysfragment_index, fragment_count, fragment_start, fragment_end, fragment_start_offset, fragment_end_offset

Annotations on audio segment fragments: Each segment is individually transcribed, so carries its own extract:txt and extract:txtLang.


Video​

Applies to: video/mp4, video/avi, video/quicktime, video/x-matroska, video/webm, and other video MIME types.

Video is the most complex input type — it produces two kinds of sub-products, each processed through media-specific paths.

Annotations on the Parent Entity​

AnnotationTypePresenceDescription
extract:metadatadictAlwaysExifTool video metadata (duration, resolution, codec, etc.)
ner:entitiesdictUsuallyNamed entities from transcript + descriptions
summary:txtstrOptionalSummary of transcribed content
rag:chunkslist[dict]UsuallyRAG chunks
rag:fulltextstrUsuallyConcatenated RAG text
materialized.ner:entitiesUsuallyNER for all children elements

Fragments Produced​

Collection TypeContentPresenceRecord Fields
video_keyframesKeyframe images, filtered by saliency and hash similarityAlways (when video has visual stream)fragment_index, fragment_count, fragment_keyframe_number, fragment_start (seconds), fragment_end (seconds)
video_audioAudio track extracted from video (single entity)Always (when video has audio stream)fragment_index: 0, fragment_count: 1, fragment_start: 0, fragment_end (duration in seconds)

Annotations on keyframe fragments: Same as Images — each keyframe is processed as a standalone image.

Annotations on the audio fragment: Same as Audio — transcribed, NER'd.


Archives / Executables / Generic / Other​

Entities that do not match a specific media type still receive baseline processing:

AnnotationPresenceDescription
extract:metadataAlways (if attachment present)ExifTool metadata
extract:txtIf Tika can parse itExtracted text; archives are always skipped
extract:txtLangIf text extractedDetected language
ner:entitiesIf text availableNamed entities from extracted text (also parses record fields like description and contents)
rag:chunksIf text availableRAG chunks built from extract:txt, record fields (description, contents), and other annotations
rag:fulltextIf text availableConcatenated RAG text

Annotation Dictionary​

Detailed schema for each annotation key.

extract:txt​

  • Type: str
  • Content: Plain text. Multi-paragraph. Line breaks separate logical sections (pages, segments, sentences).
  • Source: Tika (documents), Whisper/AssemblyAI (audio), vision LLM (images).
  • On fragments: Contains only the fragment's portion of text.
  • On parent after merge: Contains the concatenated text of all children.

extract:txtLang​

  • Type: str
  • Content: Language name string (e.g. "english", "german", "french").
  • Note: Detected from the first 100k characters of extract:txt. For images, always "english" (the captioning language).

extract:metadata​

  • Type: dict
  • Content: Keys are ExifTool field names with namespace prefixes stripped (File:, ExifTool:, SourceFile removed). Values are strings, numbers, or nested structures depending on the metadata field.
  • Examples:
{
"ImageWidth": 1920,
"ImageHeight": 1080,
"MIMEType": "image/jpeg",
"DateTimeOriginal": "2024:01:15 14:30:00",
"GPSLatitude": "48.8566",
"GPSLongitude": "2.3522",
"Duration": "00:05:32",
"AudioBitrate": "128000"
}

extract:frontmatter​

  • Type: dict
  • Content: Optional keys — only present when detected:
    • toc — table of contents
    • abstract — document abstract
    • glossary — glossary section
    • introduction — introduction text

ner:entities​

  • Type: dict
  • Content: Keys are lowercase entity labels, values are deduplicated lists of entity strings.
{
"person": ["Alice Johnson", "Bob Smith"],
"org": ["Acme Corp", "United Nations"],
"loc": ["New York", "Paris"],
"date": ["January 2024", "2023-12-01"],
}

summary:txt​

  • Type: str
  • Content: LLM-generated natural language summary. For multi-page documents with fragments, this is a hierarchical summary that considers section types.
  • Typical length: Proportional to input document and inversely proportional to fragment depth, up to around 4096 tokens.

image:annotations​

  • Type: list[dict]
  • Content: Each item has at minimum {"label": "..."}. Items from face/object detection may also include:
[
{"label": "Photo"},
{"label": "Outdoor"},
{"label": "cars"},
{"label": "face", "bbox": [120, 45, 280, 210], "confidence": 0.97,
"embedding": {"#type": "VECTOR", "data": [...], "metadata": {...}}},
{"label": "image embedding",
"embedding": {"#type": "VECTOR", "data": [...], "metadata": {...}}}
]
  • Sub-keys for filtered views:
    • image:annotations-key — object detection labels only
    • image:annotations-sensitive — sensitive content flags only
    • image:annotations-setting — image type + setting + conditions only These fields never contain embeddings.

section:type​

  • Type: str
  • Values: textual, image, tabular, list, mixed
  • Present on: Fragment entities only (pages, sections).

rag:chunks​

  • Type: list[dict]
  • Content: Array of chunk objects. Max count governed by rag_max_chunks (default: 100).
[
{
"metadata": {
"source": "entity-uid-here",
"entity_type": "os_document",
"chunk_index": 0,
"text": "The actual text content of this chunk...",
"embedding": {
"#type": "VECTOR",
"data": [0.012, -0.034, 0.056, ...],
"metadata": {
"model_name": "sentence-transformers/all-MiniLM-L6-v2",
"dim": 384
}
}
}
}
]

rag:fulltext​

  • Type: str
  • Content: All rag:chunks[*].metadata.text values concatenated.

materialized.*​

  • Type: Varies (mirrors the type of the source annotation)
  • Content: Accumulated values from child fragment annotations, written to the parent entity in the search index. The key mirrors the original annotation key prefixed with materialized..
  • Example: materialized.ner:entities contains the combined NER results from all children fragments.

Fragment Dictionary​

Common Record Fields on All Fragments​

FieldTypeAlways PresentDescription
fragment_indexint✓0-based position among siblings
fragment_countint✓Total sibling count
fragment_collection_typestr✓Category (see per-type tables below)
os_item_content_typestr✓MIME type of the fragment content
os_has_attachmentbool✓Whether binary content is stored
fragment_startint✓Start position (unit depends on type)
fragment_endint✓End position (unit depends on type)

document_pages / document_page_groups​

For page/slide-based types (PDF, DOCX, DOC, ODT, PPTX, PPT, ODP).

FieldTypeAlwaysDescription
fragment_page_numberint✓Starting page number
fragment_startint✓Start page
fragment_endint✓End page
fragment_start_offsetint◇Context overlap (chars before this range)
fragment_end_offsetint◇Context overlap (chars after this range)
os_item_namestr◇Section heading (if detected)
section:type (annotation)str✓textual, image, tabular, list, mixed

table_rows / table_row_groups​

For row-based types (XLSX, XLS, CSV, TSV, ODS).

FieldTypeAlwaysDescription
fragment_startint✓Start row index
fragment_endint✓End row index
os_item_namestr◇Sheet name or heading
section:type (annotation)str✓Always tabular

document_images​

FieldTypeAlwaysDescription
os_item_content_typestr✓Image MIME type (e.g. image/png)
fragment_indexint✓Image index within the document
AnnotationsSame as standalone Image processing

video_keyframes​

FieldTypeAlwaysDescription
fragment_keyframe_numberint✓Keyframe sequence number
fragment_startint✓Timestamp in seconds
fragment_endint✓Timestamp in seconds
os_item_content_typestr✓image/png or image/jpeg
AnnotationsSame as standalone Image processing

video_audio​

FieldTypeAlwaysDescription
fragment_startint✓Always 0
fragment_endint✓Duration in seconds (ceil)
os_item_content_typestr✓Audio MIME type
AnnotationsSame as standalone Audio processing

audio_split​

FieldTypeAlwaysDescription
fragment_startint✓Start time in seconds
fragment_endint✓End time in seconds
fragment_start_offsetint◇Overlap with previous segment (seconds)
fragment_end_offsetint◇Overlap with next segment (seconds)
Annotationsextract:txt, extract:txtLang for the segment

face_crops​

FieldTypeAlwaysDescription
fragment_image_bboxlist[int]✓[x1, y1, x2, y2] bounding box in pixels
os_item_content_typestr✓image/png
AnnotationsSingle-item image:annotations with label (= face), bbox, confidence, embedding

Shared Data Formats​

Embedding Vectors​

All embeddings in annotations share the same envelope:

{
"#type": "VECTOR",
"data": [0.012, -0.034, 0.056, ...],
"metadata": {
"model_name": "model-identifier",
"model_version": "version-string",
"dim": 512
}
}
Contextmodel_nameTypical dim
Face embeddingfacenet_pytorch_inception_resnet_v1512
Image embedding (CLIP)vitb32512
RAG chunk embedding(configurable sentence-transformer)384+

Processing Status​

Entities carry a processing_status in the search index:

StatusMeaning
RUNNINGPipeline is actively processing this entity
COMPLETEDProcessing finished successfully
FAILEDProcessing encountered an error

Cheat Sheet​

What annotations will my parent entity have?​

This table shows what is on the parent entity in OpenSearch. When an entity is split into fragments, some annotations (like extract:txt) live only on fragments and are not directly on the parent — use get_entity_annotations with recurse=True to get the merged view.

DocumentsPresentationsImagesAudioVideoSpreadsheetsArchives / Other
extract:txt◇ ^1^◇ ^1^✓◇ ^1^— ^2^◇ ^1^◇
extract:txtLang◇ ^1^◇ ^1^✓◇ ^1^— ^2^◇ ^1^◇
extract:metadata✓✓✓✓✓✓✓
ner:entities◇◇◇◇◇◇◇
summary:txt✓——◇◇——
extract:frontmatter◇——————
image:annotations——✓————
image:annotations-key——✓————
image:annotations-sensitive——✓————
image:annotations-setting——✓————
translate:txt:{lang}———◇◇——
translate:src———◇◇——
rag:chunks✓✓✓◇◇◇◇
rag:fulltext◇◇✓◇◇◇◇
materialized.*◇ ^3^◇ ^3^◇◇◇ ^3^——

✓ = always    ◇ = conditional    — = not applicable

^1^ Only on the parent when the entity was not split into fragments. When split, extract:txt and extract:txtLang live on the leaf fragments instead. ^2^ Video parent never has extract:txt directly — text lives on keyframe and audio fragments. ^3^ Present when the entity was fragmented; contains rolled-up child annotations (e.g. materialized.ner:entities).

What fragments will my entity produce?​

Input TypeFragment TypesCount
Document (PDF, DOCX, DOC, ODT)document_pages + document_page_groups + document_imagesPages: 1 per page (plus groups by max_pages). Images: varies.
Presentation (PPTX, PPT, ODP)document_pages + document_page_groups + document_images1 per slide (plus groups). Images: varies.
Spreadsheet (XLSX, XLS, CSV, TSV, ODS)table_rows (+ table_row_groups)Row-range chunks (controlled by max_rows).
Imageface_crops0 (single/large face) or N (multi-face)
Audioaudio_splitDepends on duration and segment config
Videovideo_keyframes + video_audioKeyframes: varies (filtered). Audio: exactly 1.
Archives / Executables / Other(none)Metadata-only — no fragments produced.