forked from ChelseaKR/cairn
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgauntlet_target.py
More file actions
80 lines (63 loc) · 2.93 KB
/
Copy pathgauntlet_target.py
File metadata and controls
80 lines (63 loc) · 2.93 KB
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
"""The gauntlet target adapter: Cairn's engine, wearing an evaluation harness.
This module is the interlock's hinge, and it deliberately lives on the
harness side of the dependency line: it imports nothing from the pinned
harness at module scope that the core path would need, and the harness
imports *it* through ``--callable gauntlet_target:make_target``. The core
install/lint/test path never touches gauntlet, exactly as it never touches
plumbline.
The adapter answers with :class:`~gauntlet.targets.TargetResponse` fields
derived from one place — :func:`cairn.engine.ask` — so what gauntlet grades
is what the CLI and the served interface serve:
- ``text`` is ``Answer.cited_text``: notice, quotes, inline markers. A gate
checking "every factual answer carries a source identifier" grades the
same string a terminal client receives.
- ``citations`` are the quoted sources' ids; ``context_ids`` are every source
retrieval accepted (composition's choice set), which is the honest reading
of "the context the target reports retrieving".
- ``refused`` mirrors ``kind == "refusal"``; Cairn has no escalation concept,
so ``escalated`` is always False and no crisis case may be authored against
this target until one exists.
"""
from __future__ import annotations
from functools import lru_cache
from pathlib import Path
# The harness runs from its own checkout, so every relative path in the
# config would resolve wrong. The adapter pins paths to *this* repository:
# it is Cairn's engine, at this tree's commit, that is under evaluation.
ROOT = Path(__file__).resolve().parent
@lru_cache(maxsize=1)
def _engine():
from cairn.config import Config
from cairn.engine import ask
from cairn.index import build_index
cfg = Config()
index = build_index(ROOT / cfg.corpus_path)
def answer(prompt: str, language: str):
result = ask(prompt, index, cfg, lang=language or None)
a = result.answer
cited_ids = tuple(s.source_id for s in a.sources)
context_ids = tuple(
c.passage.passage_id for t in result.attempts for c in t.trace.accepted
) or cited_ids
from gauntlet.targets import TargetResponse
return TargetResponse(
text=a.cited_text,
citations=cited_ids,
context_ids=context_ids,
refused=a.kind == "refusal",
escalated=False,
)
return answer
def make_target():
"""Factory named by ``gauntlet run --callable gauntlet_target:make_target``."""
from gauntlet.targets import CallableTarget
def provenance() -> dict[str, str]:
from cairn import __version__
from cairn.config import Config
from cairn.corpus import fingerprint
return {
"target": "cairn",
"version": __version__,
"corpus_fingerprint": fingerprint(ROOT / Config().corpus_path),
}
return CallableTarget(fn=_engine(), name="cairn", provenance_fn=provenance)