Writing plugins¶
Plugins keep provider and framework dependencies outside the core package. Public protocols cover Source, Ranker, Policy, Renderer, and PythonTokenizer.
Ranker¶
import cognoxium as cx
class KeywordRanker:
fingerprint = "keyword-v1"
def score_batch(self, query, items):
query = query.casefold()
return [float(query in item.payload.text_value().casefold()) for item in items]
frame = cx.CognitionFrame.from_records([
{"id": "a", "payload": "release ready"},
{"id": "b", "payload": "work in progress"},
])
ranked = frame.rank("release", ranker=KeywordRanker())
print(ranked.explain())
Scan[context records] -> Rank[keyword-v1]
A ranker must return one numeric score per item. Invalid lengths or non-numeric results raise PluginError.
Policy¶
class RejectUntrustedExternally:
id = "example.reject-untrusted.v1"
def evaluate(self, item, boundary):
if boundary.kind == "external" and item.trust is cx.Trust.UNTRUSTED:
return "untrusted_source"
return None
pack = frame.pack(
budget=100,
boundary=cx.Boundary.external("provider"),
policies=[RejectUntrustedExternally()],
)
A policy is called once per item and returns a stable reason code or None. Avoid network calls in this per-item method; authenticate and enrich records before packing.
Source¶
Source.load() returns an iterable of record mappings. See the complete StaticSource example in Building a CognitionFrame. The Source ID identifies the adapter; each returned item still needs a meaningful sources field.
Renderer¶
class IdRenderer:
id = "ids-v1"
def render(self, pack):
return [item.id for item in pack.items]
ids = pack.render(IdRenderer())
A renderer receives an immutable ContextPack. It must reject unsupported payloads instead of silently stringifying them.
Python tokenizer fallback¶
class WordTokenizer:
fingerprint = "words-v1"
thread_safe = True
def count_batch(self, values):
return [len(value.split()) for value in values]
profile = cx.profiles.huggingface(
WordTokenizer(),
profile_id="example:words-v1",
)
The first use emits PerformanceWarning because Python tokenization is a slower fallback. count_batch() must return one non-negative integer per value.
Reproducibility contract¶
Plugins must be deterministic for a stable fingerprint. Change the fingerprint whenever code, vocabulary, model, configuration, envelope accounting, or remote service version can change results. Cognoxium cannot validate that a fingerprint truthfully identifies external state.