@prefix : <#> .
@prefix llmr: <https://www.openlinksw.com/ontology/llm-routing#> .
@prefix schema: <http://schema.org/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dbr: <http://dbpedia.org/resource/> .

# ═══════════════════════════════════════════════════════════════════════════
# LLM Routing Ontology (llmr:) — TBox
# Authoritative term definitions for the llm-routing-skill graph.
# Contract: ontology-cross-reference-gate (preferences.ttl) — every term
# carries rdfs:label, rdfs:comment, rdfs:domain/range (properties),
# rdfs:isDefinedBy, and verified external cross-references. Terms marked
# 'no direct schema.org/DBpedia/Wikidata equivalent (checked 2026-08-19)'
# were checked and none exists; the absence is recorded per the
# superproperty-check rule rather than silently omitted.
# This file is embedded verbatim into references/routing-graph.ttl by
# scripts/build_routing_graph.py and is the single source of truth for the
# llmr: vocabulary. Registered in agent-rdf-memory/entities/ontology-terms.ttl.
# ═══════════════════════════════════════════════════════════════════════════

llmr: a owl:Ontology ;
    rdfs:label "LLM Routing Ontology"@en ;
    rdfs:comment "Model registry + capability x cost x latency graph informing intelligent LLM routing decisions. Sets are repeated triples (llmr:paretoFrontierModel, llmr:dominantDimension); ordered sequences use schema:ItemList/schema:ListItem/schema:position (escalation ladders); capability attributes use schema:additionalProperty + schema:PropertyValue. No blank nodes: reification nodes carry named hash IRIs."@en ;
    schema:name "LLM Routing Ontology"@en ;
    schema:description "Ontology for the llm-routing-skill: model registry, task taxonomy, capability x cost x latency profiles, Pareto frontiers, escalation ladders, feedback records, and governance policy. Instance data lives in references/routing-graph.ttl."@en ;
    rdfs:seeAlso <https://linkeddata.uriburner.com/DAV/demos/daas/ontology/intelligence-allocation#> .

# ── Classes ─────────────────────────────────────────────────────────────────

llmr:Model a rdfs:Class ;
    rdfs:label "LLM Model"@en ;
    rdfs:comment "A large language model offered by a vendor at a per-token price, with a capability profile, latency class, context window, and cost tier. Instances are also typed schema:SoftwareApplication."@en ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:SoftwareApplication, dbr:Language_model .

llmr:TaskType a rdfs:Class ;
    rdfs:label "Task Type"@en ;
    rdfs:comment "A fine-grained category of LLM workload (e.g. code-generation, summarization, logical-reasoning) with a required capability level, dominant capability dimensions, token sensitivity, and overqualification risk. No direct schema.org equivalent (checked 2026-08-19); schema:Action is the closest sibling but denotes an executed action, not a workload category."@en ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso <http://dbpedia.org/resource/Software_agent> .

llmr:CapabilityLevel a rdfs:Class ;
    rdfs:label "Capability Level"@en ;
    rdfs:comment "An ordered proficiency level (L1 Routine .. L5 Frontier) used as the required-capability yardstick for tasks and the achieved-capability ceiling for models."@en ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:Enumeration .

llmr:GovernancePolicy a rdfs:Class ;
    rdfs:label "Governance Policy"@en ;
    rdfs:comment "Operator-controlled routing knobs: approved models, blocked models, residency constraints, and cost-tier caps. Routing intelligence is advisory; governance stays with the operator."@en ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:Policy .

llmr:FeedbackRecord a rdfs:Class ;
    rdfs:label "Feedback Record"@en ;
    rdfs:comment "An append-only record of a routed execution's outcome — model, task, quality score, cost tier, latency, pass/fail — that drives the seed-profile refinement loop."@en ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:Review .

# ── Model properties ────────────────────────────────────────────────────────

llmr:modelId a rdf:Property ;
    rdfs:label "model id"@en ;
    rdfs:comment "Vendor's model identifier (e.g. deepseek-v4-flash). Subproperty of schema:identifier (superproperty check: schema:identifier is the canonical identifier property, verified 2026-08-19)."@en ;
    rdfs:subPropertyOf schema:identifier ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:vendor a rdf:Property ;
    rdfs:label "vendor"@en ;
    rdfs:comment "The organization offering the model. No direct schema.org equivalent for 'vendor of an LLM model' (checked 2026-08-19); schema:provider is the closest sibling."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range schema:Organization ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:provider .

llmr:inputPricePerMTok a rdf:Property ;
    rdfs:label "input price per million tokens"@en ;
    rdfs:comment "USD price per million input tokens. No direct schema.org equivalent (checked 2026-08-19): schema:price is per-unit-of-offer, not per-token; the per-MTok unit is encoded in the property name."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:decimal ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:price .

llmr:outputPricePerMTok a rdf:Property ;
    rdfs:label "output price per million tokens"@en ;
    rdfs:comment "USD price per million output tokens. No direct schema.org equivalent (checked 2026-08-19): schema:price is per-unit-of-offer, not per-token."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:decimal ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:price .

llmr:cachedInputPricePerMTok a rdf:Property ;
    rdfs:label "cached input price per million tokens"@en ;
    rdfs:comment "USD price per million cached (prompt-cached) input tokens, or absent when the model offers no cached-token pricing. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:decimal ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:price .

llmr:costTier a rdf:Property ;
    rdfs:label "cost tier"@en ;
    rdfs:comment "Cost band (low|medium|high|max) derived from output price per MTok against the thresholds in capability-profiles.json; mirrors OpenRouter's cost_tier."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:latencyClass a rdf:Property ;
    rdfs:label "latency class"@en ;
    rdfs:comment "Qualitative latency band (very-low|low|medium|high|very-high) with P50 estimates in capability-profiles.json. Seed value; refined via feedback."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:contextWindowTokens a rdf:Property ;
    rdfs:label "context window tokens"@en ;
    rdfs:comment "Approximate context window size in tokens. Seed value; refine via feedback or vendor specs."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:integer ;
    rdfs:isDefinedBy llmr: .

llmr:profileNote a rdf:Property ;
    rdfs:label "profile note"@en ;
    rdfs:comment "Free-text note on a model's capability seed (e.g. which family rule matched, or a refinement rationale). Subproperty of rdfs:comment."@en ;
    rdfs:subPropertyOf rdfs:comment ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

# ── Task properties ─────────────────────────────────────────────────────────

llmr:requiredCapabilityLevel a rdf:Property ;
    rdfs:label "required capability level"@en ;
    rdfs:comment "The minimum capability level (llmrl:L1..L5) a model must reach to be routed this task type. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:TaskType ;
    rdfs:range llmr:CapabilityLevel ;
    rdfs:isDefinedBy llmr: .

llmr:dominantDimension a rdf:Property ;
    rdfs:label "dominant capability dimension"@en ;
    rdfs:comment "A capability dimension (reasoning, code, creative, long_context, vision, tools, knowledge, math) that dominates fitness for this task type. Repeated triples form a set — never an RDF list."@en ;
    rdfs:domain llmr:TaskType ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:paretoFrontierModel a rdf:Property ;
    rdfs:label "Pareto frontier model"@en ;
    rdfs:comment "A model on the cost-quality Pareto frontier for this task type: no other model has >= capability at <= price and <= latency (strict on at least one). Repeated triples form the frontier set."@en ;
    rdfs:domain llmr:TaskType ;
    rdfs:range llmr:Model ;
    rdfs:isDefinedBy llmr: .

llmr:tokenSensitivity a rdf:Property ;
    rdfs:label "token sensitivity"@en ;
    rdfs:comment "How strongly output quality depends on input length (low|medium|high|very-high). No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:TaskType ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:overqualificationRisk a rdf:Property ;
    rdfs:label "overqualification risk"@en ;
    rdfs:comment "Risk that a frontier model is overkill for this task (low|medium|high) — high for routine tasks where cheap models suffice. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:TaskType ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

# ── Governance properties ───────────────────────────────────────────────────

llmr:approvesModel a rdf:Property ;
    rdfs:label "approves model"@en ;
    rdfs:comment "Operator-approved model id for this governance policy. Range is xsd:string (model id), not llmr:Model, because approvals may name models absent from the price feed."@en ;
    rdfs:domain llmr:GovernancePolicy ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:blocksModel a rdf:Property ;
    rdfs:label "blocks model"@en ;
    rdfs:comment "Operator-blocked model id for this governance policy. Same range rationale as llmr:approvesModel."@en ;
    rdfs:domain llmr:GovernancePolicy ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:residencyConstraint a rdf:Property ;
    rdfs:label "residency constraint"@en ;
    rdfs:comment "Data-residency region constraint for this governance policy. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:GovernancePolicy ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

# ── Feedback properties ─────────────────────────────────────────────────────

llmr:feedbackModel a rdf:Property ;
    rdfs:label "feedback model"@en ;
    rdfs:comment "The model a feedback record scored. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range llmr:Model ;
    rdfs:isDefinedBy llmr: .

llmr:feedbackTask a rdf:Property ;
    rdfs:label "feedback task"@en ;
    rdfs:comment "The task type a feedback record scored. No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range llmr:TaskType ;
    rdfs:isDefinedBy llmr: .

llmr:qualityScore a rdf:Property ;
    rdfs:label "quality score"@en ;
    rdfs:comment "Output quality score 1-5 assigned after execution. No direct schema.org equivalent (checked 2026-08-19); schema:reviewRating is the closest sibling."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range xsd:integer ;
    rdfs:isDefinedBy llmr: ;
    rdfs:seeAlso schema:reviewRating .

llmr:passedVerification a rdf:Property ;
    rdfs:label "passed verification"@en ;
    rdfs:comment "Whether the output passed the task's verification gate (boolean)."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range xsd:boolean ;
    rdfs:isDefinedBy llmr: .

llmr:observedLatency a rdf:Property ;
    rdfs:label "observed latency"@en ;
    rdfs:comment "Observed latency class during execution (very-low|low|medium|high|very-high)."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range xsd:string ;
    rdfs:isDefinedBy llmr: .

llmr:feedbackDate a rdf:Property ;
    rdfs:label "feedback date"@en ;
    rdfs:comment "ISO date the feedback was recorded."@en ;
    rdfs:domain llmr:FeedbackRecord ;
    rdfs:range xsd:date ;
    rdfs:isDefinedBy llmr: .

# ── Graph-dataset property ──────────────────────────────────────────────────

llmr:priceUpdated a rdf:Property ;
    rdfs:label "price updated"@en ;
    rdfs:comment "Date the llm-prices.com pricing feed was last updated, attached to each llmr:Model (price provenance). No direct schema.org equivalent (checked 2026-08-19)."@en ;
    rdfs:domain llmr:Model ;
    rdfs:range xsd:date ;
    rdfs:isDefinedBy llmr: .

llmr:graphPriceUpdated a rdf:Property ;
    rdfs:label "graph price updated"@en ;
    rdfs:comment "Date the llm-prices.com pricing feed was last updated, attached to the routing-graph schema:Dataset (feed date for the whole graph). Separate from llmr:priceUpdated so each property keeps a single concrete domain (Step 37: no blank-node union expressions)."@en ;
    rdfs:domain schema:Dataset ;
    rdfs:range xsd:date ;
    rdfs:isDefinedBy llmr: .
