File size: 2,331 Bytes
e379257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import sys
from pathlib import Path
import pytest
import torch

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))


class FakeTokenizer:
    """Char-level tokenizer (ids = ord % vocab); enough for encode_record / encode_glint_record."""
    vocab = 997
    pad_token_id = 0

    class _Out:
        def __init__(self, ids):
            self.input_ids = ids

    def __call__(self, text, add_special_tokens=False):
        return self._Out([1 + ord(c) % (self.vocab - 1) for c in text])

    def convert_tokens_to_ids(self, token):
        return self.vocab - 1


class FakeBackbone(torch.nn.Module):
    """Stands in for Qwen3_5ForConditionalGeneration: .model(...) -> last_hidden_state, get_output_embeddings()."""

    def __init__(self, vocab=FakeTokenizer.vocab, hidden=32):
        super().__init__()

        class Inner(torch.nn.Module):
            def __init__(self):
                super().__init__()
                self.embed = torch.nn.Embedding(vocab, hidden)
                self.mix = torch.nn.Linear(hidden, hidden)

            def forward(self, input_ids, attention_mask, use_cache=False, return_dict=True, **media):
                class O:
                    pass
                o = O(); o.last_hidden_state = torch.tanh(self.mix(self.embed(input_ids)))
                return o

        self.model = Inner()
        self.lm_head = torch.nn.Linear(hidden, vocab, bias=False)

    def get_output_embeddings(self):
        return self.lm_head


@pytest.fixture
def tok():
    return FakeTokenizer()


@pytest.fixture
def records():
    choice = {"screen": {"type": "choice", "instructions": "What screen?", "criteria": {"home": "Home", "error": "Error"}},
              "has_error": {"type": "noul", "instructions": "Is an error visible?"}}
    box = {"btn": {"type": "box", "instructions": "the primary button in `screen`"},
           "btn_visible": {"type": "noul", "instructions": "Is the primary button visible?"},
           "badge": {"type": "box", "instructions": "the red badge"}}
    return {"choice": {"id": "c", "state": {"app": "X"}, "questions": choice},
            "mixed": {"id": "m", "state": "s", "questions": {**choice, **box}},
            "box_only": {"id": "b", "state": "s", "questions": {"btn": box["btn"]}}}