Safetensors
jev-style
English
decision-index
system-one
typed-decisions
rule-based
symbolic
no-weights
zero-parameters
program-execution
chess
bm25
tool-use
deterministic
cpu
Eval Results (legacy)
Instructions to use tardellirs/prumo with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- jev-style
How to use tardellirs/prumo with jev-style:
pip install "jev-style[torch]"
from jev_style import JevStyle, noul, choice js = JevStyle.from_pretrained("tardellirs/prumo") out = js.decide("I was charged twice for one order.", { "billing": noul("This message is about billing."), "team": choice("Which team should handle it?", ["billing", "shipping", "tech"]), }) print(out["answers"]["team"]["choice"]) - Notebooks
- Google Colab
- Kaggle
File size: 3,824 Bytes
b445c46 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | """Prumo: a zero-parameter, rule-based decision engine for the Decision Index (no learned weights).
cd prumo
python -m decision_index run --engine decision_index_engine:DecisionEngine --out runs/<name>
(--option solvers=code,chess,... enables a subset; default: all)
Every question of a request goes through generic capabilities in a fixed order. Each capability reads the
*structure* of the request (Python code with a `def`, a FEN string, a list of tool schemas, candidates to rank,
a boolean expression, dates, an ordering-constraint puzzle, ...) and either returns probabilities for some
questions or passes. A question that no capability claims gets the uniform distribution and a deterministic hash
pick (expected score = chance). There are no answer tables, no benchmark names or item ids, no network access,
and nothing in the engine was fitted to data.
"""
import importlib
import time
from decision_index.engines import Engine
from prumo_rules.common import hpick
ORDER = ["code", "chess", "tools", "retrieval", "grounding", "consensus", "labels", "music", "logic", "puzzles", "dates",
"arith"]
class DecisionEngine(Engine):
name = "prumo"
latency = "In-process wall time per request, including sandboxed code execution and the node-limited chess search."
def __init__(self, **options):
super().__init__(**options)
names = options.get("solvers") or ",".join(ORDER)
names = names if isinstance(names, str) else ",".join(names)
self.solvers = [(n, importlib.import_module(f"prumo_rules.{n}")) for n in names.split(",") if n]
from prumo_rules import sandbox
self.provenance = {"kind": "rule-based, no weights", "learned_parameters": 0,
"capabilities": [n for n, _ in self.solvers], "code_isolation": sandbox.isolation()}
def synchronize(self):
pass
def close(self):
pass
def decide(self, state, questions):
claimed, trace = {}, {}
for n, mod in self.solvers:
todo = {k: q for k, q in questions.items() if k not in claimed}
if not todo:
break
t = time.perf_counter()
try:
got = mod.solve(state, todo) or {}
except Exception as e: # a capability bug must never sink the request: fall through to the next one
got = {}
trace[n + "_error"] = f"{type(e).__name__}: {e}"[:200]
for k, v in got.items():
if k in todo and v:
claimed[k] = v
trace[k] = n
if got:
trace[n + "_ms"] = round(1000 * (time.perf_counter() - t), 1)
return claimed, trace
def __call__(self, state, questions):
claimed, trace = self.decide(state, questions)
answers = {}
for k, q in questions.items():
v = claimed.get(k)
if q["type"] == "noul":
p = v.get("noul", 0.5) if v else 0.5
answers[k] = {"type": "noul", "noul": float(min(1.0, max(0.0, p)))}
continue
keys = list(q["criteria"])
if v:
probs = {o: float(max(0.0, v.get(o, 0.0))) for o in keys}
z = sum(probs.values())
probs = {o: p / z for o, p in probs.items()} if z > 0 else {o: 1 / len(keys) for o in keys}
else:
probs = {o: 1 / len(keys) for o in keys}
top = max(probs.values())
best = [o for o in keys if probs[o] >= top - 1e-12]
choice = best[0] if len(best) == 1 else hpick(best, k + str(len(keys)))
answers[k] = {"type": "choice", "choice": choice, "probabilities": probs}
return {"model": "prumo", "answers": answers}, {"solved_by": trace}
|