{
 "version": "2026-10-04",
 "notes": "Greedy (temperature 0), thinking disabled via chat_template_kwargs.enable_thinking=false for every engine, fixed max_tokens per task. Code in prompts is unmodified CPython 3.14 stdlib source (sched, colorsys with one injected bug, graphlib, getopt, fnmatch).",
 "tasks": [
  {
   "id": "code_rename",
   "category": "Code edit: rename across a file",
   "copy_heavy": true,
   "max_tokens": 2600,
   "messages": [
    {
     "role": "user",
     "content": "Rename the method `enterabs` to `enter_absolute` everywhere in this module: the definition, every call site and every mention in docstrings or comments. Change nothing else. Reply with the complete updated file in one ```python block and no other text.\n\n```python\n\"\"\"A generally useful event scheduler class.\n\nEach instance of this class manages its own queue.\nNo multi-threading is implied; you are supposed to hack that\nyourself, or use a single instance per application.\n\nEach instance is parametrized with two functions, one that is\nsupposed to return the current time, one that is supposed to\nimplement a delay.  You can implement real-time scheduling by\nsubstituting time and sleep from built-in module time, or you can\nimplement simulated time by writing your own functions.  This can\nalso be used to integrate scheduling with STDWIN events; the delay\nfunction is allowed to modify the queue.  Time can be expressed as\nintegers or floating-point numbers, as long as it is consistent.\n\nEvents are specified by tuples (time, priority, action, argument, kwargs).\nAs in UNIX, lower priority numbers mean higher priority; in this\nway the queue can be maintained as a priority queue.  Execution of the\nevent means calling the action function, passing it the argument\nsequence in \"argument\" (remember that in Python, multiple function\narguments are be packed in a sequence) and keyword parameters in \"kwargs\".\nThe action function may be an instance method so it\nhas another way to reference private data (besides global variables).\n\"\"\"\n\nimport time\nimport heapq\nfrom collections import namedtuple\nfrom itertools import count\nimport threading\nfrom time import monotonic as _time\n\n__all__ = [\"scheduler\"]\n\nEvent = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs')\nEvent.time.__doc__ = ('''Numeric type compatible with the return value of the\ntimefunc function passed to the constructor.''')\nEvent.priority.__doc__ = ('''Events scheduled for the same time will be executed\nin the order of their priority.''')\nEvent.sequence.__doc__ = ('''A continually increasing sequence number that\n    separates events if time and priority are equal.''')\nEvent.action.__doc__ = ('''Executing the event means executing\naction(*argument, **kwargs)''')\nEvent.argument.__doc__ = ('''argument is a sequence holding the positional\narguments for the action.''')\nEvent.kwargs.__doc__ = ('''kwargs is a dictionary holding the keyword\narguments for the action.''')\n\n_sentinel = object()\n\nclass scheduler:\n\n    def __init__(self, timefunc=_time, delayfunc=time.sleep):\n        \"\"\"Initialize a new instance, passing the time and delay\n        functions\"\"\"\n        self._queue = []\n        self._lock = threading.RLock()\n        self.timefunc = timefunc\n        self.delayfunc = delayfunc\n        self._sequence_generator = count()\n\n    def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):\n        \"\"\"Enter a new event in the queue at an absolute time.\n\n        Returns an ID for the event which can be used to remove it,\n        if necessary.\n\n        \"\"\"\n        if kwargs is _sentinel:\n            kwargs = {}\n\n        with self._lock:\n            event = Event(time, priority, next(self._sequence_generator),\n                          action, argument, kwargs)\n            heapq.heappush(self._queue, event)\n        return event # The ID\n\n    def enter(self, delay, priority, action, argument=(), kwargs=_sentinel):\n        \"\"\"A variant that specifies the time as a relative time.\n\n        This is actually the more commonly used interface.\n\n        \"\"\"\n        time = self.timefunc() + delay\n        return self.enterabs(time, priority, action, argument, kwargs)\n\n    def cancel(self, event):\n        \"\"\"Remove an event from the queue.\n\n        This must be presented the ID as returned by enter().\n        If the event is not in the queue, this raises ValueError.\n\n        \"\"\"\n        with self._lock:\n            self._queue.remove(event)\n            heapq.heapify(self._queue)\n\n    def empty(self):\n        \"\"\"Check whether the queue is empty.\"\"\"\n        with self._lock:\n            return not self._queue\n\n    def run(self, blocking=True):\n        \"\"\"Execute events until the queue is empty.\n        If blocking is False executes the scheduled events due to\n        expire soonest (if any) and then return the deadline of the\n        next scheduled call in the scheduler.\n\n        When there is a positive delay until the first event, the\n        delay function is called and the event is left in the queue;\n        otherwise, the event is removed from the queue and executed\n        (its action function is called, passing it the argument).  If\n        the delay function returns prematurely, it is simply\n        restarted.\n\n        It is legal for both the delay function and the action\n        function to modify the queue or to raise an exception;\n        exceptions are not caught but the scheduler's state remains\n        well-defined so run() may be called again.\n\n        A questionable hack is added to allow other threads to run:\n        just after an event is executed, a delay of 0 is executed, to\n        avoid monopolizing the CPU when other threads are also\n        runnable.\n\n        \"\"\"\n        # localize variable access to minimize overhead\n        # and to improve thread safety\n        lock = self._lock\n        q = self._queue\n        delayfunc = self.delayfunc\n        timefunc = self.timefunc\n        pop = heapq.heappop\n        while True:\n            with lock:\n                if not q:\n                    break\n                (time, priority, sequence, action,\n                 argument, kwargs) = q[0]\n                now = timefunc()\n                if time > now:\n                    delay = True\n                else:\n                    delay = False\n                    pop(q)\n            if delay:\n                if not blocking:\n                    return time - now\n                delayfunc(time - now)\n            else:\n                action(*argument, **kwargs)\n                delayfunc(0)   # Let other threads run\n\n    @property\n    def queue(self):\n        \"\"\"An ordered list of upcoming events.\n\n        Events are named tuples with fields for:\n            time, priority, action, arguments, kwargs\n\n        \"\"\"\n        # Use heapq to sort the queue rather than using 'sorted(self._queue)'.\n        # With heapq, two events scheduled at the same time will show in\n        # the actual order they would be retrieved.\n        with self._lock:\n            events = self._queue[:]\n        return list(map(heapq.heappop, [events]*len(events)))\n```"
    }
   ]
  },
  {
   "id": "code_bugfix_file",
   "category": "Code edit: fix a bug, return whole file",
   "copy_heavy": true,
   "max_tokens": 2400,
   "messages": [
    {
     "role": "user",
     "content": "A user reports that colorsys.hsv_to_rgb returns the wrong colour for hues between 0.5 and 0.667 (for example hsv_to_rgb(0.55, 1, 1) should be mostly blue-cyan). Find and fix the bug. Reply with the complete corrected file in one ```python block, then one sentence explaining the fix.\n\n```python\n\"\"\"Conversion functions between RGB and other color systems.\n\nThis modules provides two functions for each color system ABC:\n\n  rgb_to_abc(r, g, b) --> a, b, c\n  abc_to_rgb(a, b, c) --> r, g, b\n\nAll inputs and outputs are triples of floats in the range [0.0...1.0]\n(with the exception of I and Q, which covers a slightly larger range).\nInputs outside the valid range may cause exceptions or invalid outputs.\n\nSupported color systems:\nRGB: Red, Green, Blue components\nYIQ: Luminance, Chrominance (used by composite video signals)\nHLS: Hue, Luminance, Saturation\nHSV: Hue, Saturation, Value\n\"\"\"\n\n# References:\n# http://en.wikipedia.org/wiki/YIQ\n# http://en.wikipedia.org/wiki/HLS_color_space\n# http://en.wikipedia.org/wiki/HSV_color_space\n\n__all__ = [\"rgb_to_yiq\",\"yiq_to_rgb\",\"rgb_to_hls\",\"hls_to_rgb\",\n           \"rgb_to_hsv\",\"hsv_to_rgb\"]\n\n# Some floating-point constants\n\nONE_THIRD = 1.0/3.0\nONE_SIXTH = 1.0/6.0\nTWO_THIRD = 2.0/3.0\n\n# YIQ: used by composite video signals (linear combinations of RGB)\n# Y: perceived grey level (0.0 == black, 1.0 == white)\n# I, Q: color components\n#\n# There are a great many versions of the constants used in these formulae.\n# The ones in this library uses constants from the FCC version of NTSC.\n\ndef rgb_to_yiq(r, g, b):\n    y = 0.30*r + 0.59*g + 0.11*b\n    i = 0.74*(r-y) - 0.27*(b-y)\n    q = 0.48*(r-y) + 0.41*(b-y)\n    return (y, i, q)\n\ndef yiq_to_rgb(y, i, q):\n    # r = y + (0.27*q + 0.41*i) / (0.74*0.41 + 0.27*0.48)\n    # b = y + (0.74*q - 0.48*i) / (0.74*0.41 + 0.27*0.48)\n    # g = y - (0.30*(r-y) + 0.11*(b-y)) / 0.59\n\n    r = y + 0.9468822170900693*i + 0.6235565819861433*q\n    g = y - 0.27478764629897834*i - 0.6356910791873801*q\n    b = y - 1.1085450346420322*i + 1.7090069284064666*q\n\n    if r < 0.0:\n        r = 0.0\n    if g < 0.0:\n        g = 0.0\n    if b < 0.0:\n        b = 0.0\n    if r > 1.0:\n        r = 1.0\n    if g > 1.0:\n        g = 1.0\n    if b > 1.0:\n        b = 1.0\n    return (r, g, b)\n\n\n# HLS: Hue, Luminance, Saturation\n# H: position in the spectrum\n# L: color lightness\n# S: color saturation\n\ndef rgb_to_hls(r, g, b):\n    maxc = max(r, g, b)\n    minc = min(r, g, b)\n    sumc = (maxc+minc)\n    rangec = (maxc-minc)\n    l = sumc/2.0\n    if minc == maxc:\n        return 0.0, l, 0.0\n    if l <= 0.5:\n        s = rangec / sumc\n    else:\n        s = rangec / (2.0-maxc-minc)  # Not always 2.0-sumc: gh-106498.\n    rc = (maxc-r) / rangec\n    gc = (maxc-g) / rangec\n    bc = (maxc-b) / rangec\n    if r == maxc:\n        h = bc-gc\n    elif g == maxc:\n        h = 2.0+rc-bc\n    else:\n        h = 4.0+gc-rc\n    h = (h/6.0) % 1.0\n    return h, l, s\n\ndef hls_to_rgb(h, l, s):\n    if s == 0.0:\n        return l, l, l\n    if l <= 0.5:\n        m2 = l * (1.0+s)\n    else:\n        m2 = l+s-(l*s)\n    m1 = 2.0*l - m2\n    return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD))\n\ndef _v(m1, m2, hue):\n    hue = hue % 1.0\n    if hue < ONE_SIXTH:\n        return m1 + (m2-m1)*hue*6.0\n    if hue < 0.5:\n        return m2\n    if hue < TWO_THIRD:\n        return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0\n    return m1\n\n\n# HSV: Hue, Saturation, Value\n# H: position in the spectrum\n# S: color saturation (\"purity\")\n# V: color brightness\n\ndef rgb_to_hsv(r, g, b):\n    maxc = max(r, g, b)\n    minc = min(r, g, b)\n    rangec = (maxc-minc)\n    v = maxc\n    if minc == maxc:\n        return 0.0, 0.0, v\n    s = rangec / maxc\n    rc = (maxc-r) / rangec\n    gc = (maxc-g) / rangec\n    bc = (maxc-b) / rangec\n    if r == maxc:\n        h = bc-gc\n    elif g == maxc:\n        h = 2.0+rc-bc\n    else:\n        h = 4.0+gc-rc\n    h = (h/6.0) % 1.0\n    return h, s, v\n\ndef hsv_to_rgb(h, s, v):\n    if s == 0.0:\n        return v, v, v\n    i = int(h*6.0) # XXX assume int() truncates!\n    f = (h*6.0) - i\n    p = v*(1.0 - s)\n    q = v*(1.0 - s*f)\n    t = v*(1.0 - s*(1.0-f))\n    i = i%6\n    if i == 0:\n        return v, t, p\n    if i == 1:\n        return q, v, p\n    if i == 2:\n        return p, v, t\n    if i == 3:\n        return p, v, q\n    if i == 4:\n        return t, p, v\n    if i == 5:\n        return v, p, q\n    # Cannot get here\n```"
    }
   ]
  },
  {
   "id": "apply_change_request",
   "category": "Code edit: apply review comments",
   "copy_heavy": true,
   "max_tokens": 3000,
   "messages": [
    {
     "role": "user",
     "content": "Apply these review comments to graphlib.py and return the complete updated file in one ```python block, no other text:\n1. Rename the attribute `npredecessors` to `num_predecessors` everywhere.\n2. In `TopologicalSorter.add`, raise `TypeError` instead of `ValueError` when called after `prepare()`, and update the message accordingly.\n3. Add a `__repr__` to `TopologicalSorter` that returns `TopologicalSorter(nodes=<number of nodes>)`.\n\n```python\nfrom types import GenericAlias\n\n__all__ = [\"TopologicalSorter\", \"CycleError\"]\n\n_NODE_OUT = -1\n_NODE_DONE = -2\n\n\nclass _NodeInfo:\n    __slots__ = \"node\", \"npredecessors\", \"successors\"\n\n    def __init__(self, node):\n        # The node this class is augmenting.\n        self.node = node\n\n        # Number of predecessors, generally >= 0. When this value falls to 0,\n        # and is returned by get_ready(), this is set to _NODE_OUT and when the\n        # node is marked done by a call to done(), set to _NODE_DONE.\n        self.npredecessors = 0\n\n        # List of successor nodes. The list can contain duplicated elements as\n        # long as they're all reflected in the successor's npredecessors attribute.\n        self.successors = []\n\n\nclass CycleError(ValueError):\n    \"\"\"Subclass of ValueError raised by TopologicalSorter.prepare if cycles\n    exist in the working graph.\n\n    If multiple cycles exist, only one undefined choice among them will be reported\n    and included in the exception. The detected cycle can be accessed via the second\n    element in the *args* attribute of the exception instance and consists in a list\n    of nodes, such that each node is, in the graph, an immediate predecessor of the\n    next node in the list. In the reported list, the first and the last node will be\n    the same, to make it clear that it is cyclic.\n    \"\"\"\n\n    pass\n\n\nclass TopologicalSorter:\n    \"\"\"Provides functionality to topologically sort a graph of hashable nodes\"\"\"\n\n    def __init__(self, graph=None):\n        self._node2info = {}\n        self._ready_nodes = None\n        self._npassedout = 0\n        self._nfinished = 0\n\n        if graph is not None:\n            for node, predecessors in graph.items():\n                self.add(node, *predecessors)\n\n    def _get_nodeinfo(self, node):\n        if (result := self._node2info.get(node)) is None:\n            self._node2info[node] = result = _NodeInfo(node)\n        return result\n\n    def add(self, node, *predecessors):\n        \"\"\"Add a new node and its predecessors to the graph.\n\n        Both the *node* and all elements in *predecessors* must be hashable.\n\n        If called multiple times with the same node argument, the set of dependencies\n        will be the union of all dependencies passed in.\n\n        It is possible to add a node with no dependencies (*predecessors* is not provided)\n        as well as provide a dependency twice. If a node that has not been provided before\n        is included among *predecessors* it will be automatically added to the graph with\n        no predecessors of its own.\n\n        Raises ValueError if called after \"prepare\".\n        \"\"\"\n        if self._ready_nodes is not None:\n            raise ValueError(\"Nodes cannot be added after a call to prepare()\")\n\n        # Create the node -> predecessor edges\n        nodeinfo = self._get_nodeinfo(node)\n        nodeinfo.npredecessors += len(predecessors)\n\n        # Create the predecessor -> node edges\n        for pred in predecessors:\n            pred_info = self._get_nodeinfo(pred)\n            pred_info.successors.append(node)\n\n    def prepare(self):\n        \"\"\"Mark the graph as finished and check for cycles in the graph.\n\n        If any cycle is detected, \"CycleError\" will be raised, but \"get_ready\" can\n        still be used to obtain as many nodes as possible until cycles block more\n        progress. After a call to this function, the graph cannot be modified and\n        therefore no more nodes can be added using \"add\".\n\n        Raise ValueError if nodes have already been passed out of the sorter.\n\n        \"\"\"\n        if self._npassedout > 0:\n            raise ValueError(\"cannot prepare() after starting sort\")\n\n        if self._ready_nodes is None:\n            self._ready_nodes = [\n                i.node for i in self._node2info.values() if i.npredecessors == 0\n            ]\n        # ready_nodes is set before we look for cycles on purpose:\n        # if the user wants to catch the CycleError, that's fine,\n        # they can continue using the instance to grab as many\n        # nodes as possible before cycles block more progress\n        cycle = self._find_cycle()\n        if cycle:\n            raise CycleError(\"nodes are in a cycle\", cycle)\n\n    def get_ready(self):\n        \"\"\"Return a tuple of all the nodes that are ready.\n\n        Initially it returns all nodes with no predecessors; once those are marked\n        as processed by calling \"done\", further calls will return all new nodes that\n        have all their predecessors already processed. Once no more progress can be made,\n        empty tuples are returned.\n\n        Raises ValueError if called without calling \"prepare\" previously.\n        \"\"\"\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n\n        # Get the nodes that are ready and mark them\n        result = tuple(self._ready_nodes)\n        n2i = self._node2info\n        for node in result:\n            n2i[node].npredecessors = _NODE_OUT\n\n        # Clean the list of nodes that are ready and update\n        # the counter of nodes that we have returned.\n        self._ready_nodes.clear()\n        self._npassedout += len(result)\n\n        return result\n\n    def is_active(self):\n        \"\"\"Return ``True`` if more progress can be made and ``False`` otherwise.\n\n        Progress can be made if cycles do not block the resolution and either there\n        are still nodes ready that haven't yet been returned by \"get_ready\" or the\n        number of nodes marked \"done\" is less than the number that have been returned\n        by \"get_ready\".\n\n        Raises ValueError if called without calling \"prepare\" previously.\n        \"\"\"\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n        return self._nfinished < self._npassedout or bool(self._ready_nodes)\n\n    def __bool__(self):\n        return self.is_active()\n\n    def done(self, *nodes):\n        \"\"\"Marks a set of nodes returned by \"get_ready\" as processed.\n\n        This method unblocks any successor of each node in *nodes* for being returned\n        in the future by a call to \"get_ready\".\n\n        Raises ValueError if any node in *nodes* has already been marked as\n        processed by a previous call to this method, if a node was not added to the\n        graph by using \"add\" or if called without calling \"prepare\" previously or if\n        node has not yet been returned by \"get_ready\".\n        \"\"\"\n\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n\n        n2i = self._node2info\n\n        for node in nodes:\n\n            # Check if we know about this node (it was added previously using add()\n            if (nodeinfo := n2i.get(node)) is None:\n                raise ValueError(f\"node {node!r} was not added using add()\")\n\n            # If the node has not being returned (marked as ready) previously, inform the user.\n            stat = nodeinfo.npredecessors\n            if stat != _NODE_OUT:\n                if stat >= 0:\n                    raise ValueError(\n                        f\"node {node!r} was not passed out (still not ready)\"\n                    )\n                elif stat == _NODE_DONE:\n                    raise ValueError(f\"node {node!r} was already marked done\")\n                else:\n                    assert False, f\"node {node!r}: unknown status {stat}\"\n\n            # Mark the node as processed\n            nodeinfo.npredecessors = _NODE_DONE\n\n            # Go to all the successors and reduce the number of predecessors, collecting all the ones\n            # that are ready to be returned in the next get_ready() call.\n            for successor in nodeinfo.successors:\n                successor_info = n2i[successor]\n                successor_info.npredecessors -= 1\n                if successor_info.npredecessors == 0:\n                    self._ready_nodes.append(successor)\n            self._nfinished += 1\n\n    def _find_cycle(self):\n        n2i = self._node2info\n        stack = []\n        itstack = []\n        seen = set()\n        node2stacki = {}\n\n        for node in n2i:\n            if node in seen:\n                continue\n\n            while True:\n                if node in seen:\n                    # If we have seen already the node and is in the\n                    # current stack we have found a cycle.\n                    if node in node2stacki:\n                        return stack[node2stacki[node] :] + [node]\n                    # else go on to get next successor\n                else:\n                    seen.add(node)\n                    itstack.append(iter(n2i[node].successors).__next__)\n                    node2stacki[node] = len(stack)\n                    stack.append(node)\n\n                # Backtrack to the topmost stack entry with\n                # at least another successor.\n                while stack:\n                    try:\n                        node = itstack[-1]()\n                        break\n                    except StopIteration:\n                        del node2stacki[stack.pop()]\n                        itstack.pop()\n                else:\n                    break\n        return None\n\n    def static_order(self):\n        \"\"\"Returns an iterable of nodes in a topological order.\n\n        The particular order that is returned may depend on the specific\n        order in which the items were inserted in the graph.\n\n        Using this method does not require to call \"prepare\" or \"done\". If any\n        cycle is detected, :exc:`CycleError` will be raised.\n        \"\"\"\n        self.prepare()\n        while self.is_active():\n            node_group = self.get_ready()\n            yield from node_group\n            self.done(*node_group)\n\n    __class_getitem__ = classmethod(GenericAlias)\n```"
    }
   ]
  },
  {
   "id": "unified_diff",
   "category": "Code edit: produce a unified diff",
   "copy_heavy": true,
   "max_tokens": 900,
   "messages": [
    {
     "role": "user",
     "content": "Make `fnmatch.filter` and `fnmatch.filterfalse` skip `None` entries in `names` instead of failing. Output only a unified diff (git style, with a/ and b/ paths for Lib/fnmatch.py and 3 lines of context) that applies cleanly to this file.\n\n```python\n\"\"\"Filename matching with shell patterns.\n\nfnmatch(FILENAME, PATTERN) matches according to the local convention.\nfnmatchcase(FILENAME, PATTERN) always takes case in account.\n\nThe functions operate by translating the pattern into a regular\nexpression.  They cache the compiled regular expressions for speed.\n\nThe function translate(PATTERN) returns a regular expression\ncorresponding to PATTERN.  (It does not compile it.)\n\"\"\"\n\nimport functools\nimport itertools\nimport os\nimport posixpath\nimport re\n\n__all__ = [\"filter\", \"filterfalse\", \"fnmatch\", \"fnmatchcase\", \"translate\"]\n\n\ndef fnmatch(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN.\n\n    Patterns are Unix shell style:\n\n    *       matches everything\n    ?       matches any single character\n    [seq]   matches any character in seq\n    [!seq]  matches any char not in seq\n\n    An initial period in FILENAME is not special.\n    Both FILENAME and PATTERN are first case-normalized\n    if the operating system requires it.\n    If you don't want this, use fnmatchcase(FILENAME, PATTERN).\n    \"\"\"\n    name = os.path.normcase(name)\n    pat = os.path.normcase(pat)\n    return fnmatchcase(name, pat)\n\n\n@functools.lru_cache(maxsize=32768, typed=True)\ndef _compile_pattern(pat):\n    if isinstance(pat, bytes):\n        pat_str = str(pat, 'ISO-8859-1')\n        res_str = translate(pat_str)\n        res = bytes(res_str, 'ISO-8859-1')\n    else:\n        res = translate(pat)\n    return re.compile(res).match\n\n\ndef filter(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that match PAT.\"\"\"\n    result = []\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        for name in names:\n            if match(name):\n                result.append(name)\n    else:\n        for name in names:\n            if match(os.path.normcase(name)):\n                result.append(name)\n    return result\n\n\ndef filterfalse(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that do not match PAT.\"\"\"\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        return list(itertools.filterfalse(match, names))\n\n    result = []\n    for name in names:\n        if match(os.path.normcase(name)) is None:\n            result.append(name)\n    return result\n\n\ndef fnmatchcase(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN, including case.\n\n    This is a version of fnmatch() which doesn't case-normalize\n    its arguments.\n    \"\"\"\n    match = _compile_pattern(pat)\n    return match(name) is not None\n\n\ndef translate(pat):\n    \"\"\"Translate a shell PATTERN to a regular expression.\n\n    There is no way to quote meta-characters.\n    \"\"\"\n\n    parts, star_indices = _translate(pat, '*', '.')\n    return _join_translated_parts(parts, star_indices)\n\n\n_re_setops_sub = re.compile(r'([&~|])').sub\n_re_escape = functools.lru_cache(maxsize=512)(re.escape)\n\n\ndef _translate(pat, star, question_mark):\n    res = []\n    add = res.append\n    star_indices = []\n\n    i, n = 0, len(pat)\n    while i < n:\n        c = pat[i]\n        i = i+1\n        if c == '*':\n            # store the position of the wildcard\n            star_indices.append(len(res))\n            add(star)\n            # compress consecutive `*` into one\n            while i < n and pat[i] == '*':\n                i += 1\n        elif c == '?':\n            add(question_mark)\n        elif c == '[':\n            j = i\n            if j < n and pat[j] == '!':\n                j = j+1\n            if j < n and pat[j] == ']':\n                j = j+1\n            while j < n and pat[j] != ']':\n                j = j+1\n            if j >= n:\n                add('\\\\[')\n            else:\n                stuff = pat[i:j]\n                if '-' not in stuff:\n                    stuff = stuff.replace('\\\\', r'\\\\')\n                else:\n                    chunks = []\n                    k = i+2 if pat[i] == '!' else i+1\n                    while True:\n                        k = pat.find('-', k, j)\n                        if k < 0:\n                            break\n                        chunks.append(pat[i:k])\n                        i = k+1\n                        k = k+3\n                    chunk = pat[i:j]\n                    if chunk:\n                        chunks.append(chunk)\n                    else:\n                        chunks[-1] += '-'\n                    # Remove empty ranges -- invalid in RE.\n                    for k in range(len(chunks)-1, 0, -1):\n                        if chunks[k-1][-1] > chunks[k][0]:\n                            chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]\n                            del chunks[k]\n                    # Escape backslashes and hyphens for set difference (--).\n                    # Hyphens that create ranges shouldn't be escaped.\n                    stuff = '-'.join(s.replace('\\\\', r'\\\\').replace('-', r'\\-')\n                                     for s in chunks)\n                i = j+1\n                if not stuff:\n                    # Empty range: never match.\n                    add('(?!)')\n                elif stuff == '!':\n                    # Negated empty range: match any character.\n                    add('.')\n                else:\n                    # Escape set operations (&&, ~~ and ||).\n                    stuff = _re_setops_sub(r'\\\\\\1', stuff)\n                    if stuff[0] == '!':\n                        stuff = '^' + stuff[1:]\n                    elif stuff[0] in ('^', '['):\n                        stuff = '\\\\' + stuff\n                    add(f'[{stuff}]')\n        else:\n            add(_re_escape(c))\n    assert i == n\n    return res, star_indices\n\n\ndef _join_translated_parts(parts, star_indices):\n    if not star_indices:\n        return fr'(?s:{\"\".join(parts)})\\z'\n    iter_star_indices = iter(star_indices)\n    j = next(iter_star_indices)\n    buffer = parts[:j]  # fixed pieces at the start\n    append, extend = buffer.append, buffer.extend\n    i = j + 1\n    for j in iter_star_indices:\n        # Now deal with STAR fixed STAR fixed ...\n        # For an interior `STAR fixed` pairing, we want to do a minimal\n        # .*? match followed by `fixed`, with no possibility of backtracking.\n        # Atomic groups (\"(?>...)\") allow us to spell that directly.\n        # Note: people rely on the undocumented ability to join multiple\n        # translate() results together via \"|\" to build large regexps matching\n        # \"one of many\" shell patterns.\n        append('(?>.*?')\n        extend(parts[i:j])\n        append(')')\n        i = j + 1\n    append('.*')\n    extend(parts[i:])\n    res = ''.join(buffer)\n    return fr'(?s:{res})\\z'\n```"
    }
   ]
  },
  {
   "id": "json_transform",
   "category": "JSON transform (rename keys, convert types)",
   "copy_heavy": true,
   "max_tokens": 2600,
   "messages": [
    {
     "role": "user",
     "content": "Convert this JSON array: rename every key from snake_case to camelCase, convert `unit_price` from a string to a number, and keep the order of records and keys. Output only the resulting JSON, pretty-printed with 2-space indentation.\n\n[\n  {\n    \"product_id\": 1000,\n    \"product_name\": \"Stainless Steel Water Bottle 750ml\",\n    \"unit_price\": \"24.99\",\n    \"stock_level\": 132,\n    \"is_active\": true,\n    \"category_name\": \"Outdoor\"\n  },\n  {\n    \"product_id\": 1001,\n    \"product_name\": \"Bamboo Cutting Board Large\",\n    \"unit_price\": \"34.50\",\n    \"stock_level\": 48,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1002,\n    \"product_name\": \"Wireless Ergonomic Mouse\",\n    \"unit_price\": \"39.00\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1003,\n    \"product_name\": \"Cotton Crew Socks 6-Pack\",\n    \"unit_price\": \"18.75\",\n    \"stock_level\": 260,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1004,\n    \"product_name\": \"LED Desk Lamp with USB Port\",\n    \"unit_price\": \"45.99\",\n    \"stock_level\": 71,\n    \"is_active\": true,\n    \"category_name\": \"Home Office\"\n  },\n  {\n    \"product_id\": 1005,\n    \"product_name\": \"Cast Iron Skillet 12 inch\",\n    \"unit_price\": \"52.00\",\n    \"stock_level\": 33,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1006,\n    \"product_name\": \"Noise Cancelling Earbuds\",\n    \"unit_price\": \"129.00\",\n    \"stock_level\": 15,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1007,\n    \"product_name\": \"Yoga Mat 6mm Non-Slip\",\n    \"unit_price\": \"29.95\",\n    \"stock_level\": 88,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1008,\n    \"product_name\": \"Insulated Lunch Bag\",\n    \"unit_price\": \"21.49\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1009,\n    \"product_name\": \"Merino Wool Beanie\",\n    \"unit_price\": \"27.00\",\n    \"stock_level\": 140,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1010,\n    \"product_name\": \"Portable Phone Charger 10000mAh\",\n    \"unit_price\": \"32.99\",\n    \"stock_level\": 64,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1011,\n    \"product_name\": \"Hiking Daypack 22L\",\n    \"unit_price\": \"64.00\",\n    \"stock_level\": 27,\n    \"is_active\": true,\n    \"category_name\": \"Outdoor\"\n  },\n  {\n    \"product_id\": 1012,\n    \"product_name\": \"Glass Food Storage Set 10-Piece\",\n    \"unit_price\": \"38.25\",\n    \"stock_level\": 52,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1013,\n    \"product_name\": \"Adjustable Dumbbell Pair 25lb\",\n    \"unit_price\": \"149.00\",\n    \"stock_level\": 9,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1014,\n    \"product_name\": \"Mechanical Keyboard Brown Switches\",\n    \"unit_price\": \"89.99\",\n    \"stock_level\": 22,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1015,\n    \"product_name\": \"Linen Throw Pillow Cover 18x18\",\n    \"unit_price\": \"16.00\",\n    \"stock_level\": 175,\n    \"is_active\": true,\n    \"category_name\": \"Home\"\n  },\n  {\n    \"product_id\": 1016,\n    \"product_name\": \"French Press Coffee Maker 1L\",\n    \"unit_price\": \"28.50\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1017,\n    \"product_name\": \"Rain Jacket Packable\",\n    \"unit_price\": \"79.00\",\n    \"stock_level\": 41,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1018,\n    \"product_name\": \"Resistance Bands Set of 5\",\n    \"unit_price\": \"19.99\",\n    \"stock_level\": 120,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1019,\n    \"product_name\": \"Monitor Stand Riser Wood\",\n    \"unit_price\": \"42.00\",\n    \"stock_level\": 36,\n    \"is_active\": true,\n    \"category_name\": \"Home Office\"\n  }\n]"
    }
   ]
  },
  {
   "id": "json_to_csv",
   "category": "Format conversion: JSON to CSV",
   "copy_heavy": true,
   "max_tokens": 1200,
   "messages": [
    {
     "role": "user",
     "content": "Convert this JSON array to CSV with a header row. Use the keys as column names in their original order, write booleans as true/false, and output only the CSV inside one ```csv block.\n\n[\n  {\n    \"product_id\": 1000,\n    \"product_name\": \"Stainless Steel Water Bottle 750ml\",\n    \"unit_price\": \"24.99\",\n    \"stock_level\": 132,\n    \"is_active\": true,\n    \"category_name\": \"Outdoor\"\n  },\n  {\n    \"product_id\": 1001,\n    \"product_name\": \"Bamboo Cutting Board Large\",\n    \"unit_price\": \"34.50\",\n    \"stock_level\": 48,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1002,\n    \"product_name\": \"Wireless Ergonomic Mouse\",\n    \"unit_price\": \"39.00\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1003,\n    \"product_name\": \"Cotton Crew Socks 6-Pack\",\n    \"unit_price\": \"18.75\",\n    \"stock_level\": 260,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1004,\n    \"product_name\": \"LED Desk Lamp with USB Port\",\n    \"unit_price\": \"45.99\",\n    \"stock_level\": 71,\n    \"is_active\": true,\n    \"category_name\": \"Home Office\"\n  },\n  {\n    \"product_id\": 1005,\n    \"product_name\": \"Cast Iron Skillet 12 inch\",\n    \"unit_price\": \"52.00\",\n    \"stock_level\": 33,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1006,\n    \"product_name\": \"Noise Cancelling Earbuds\",\n    \"unit_price\": \"129.00\",\n    \"stock_level\": 15,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1007,\n    \"product_name\": \"Yoga Mat 6mm Non-Slip\",\n    \"unit_price\": \"29.95\",\n    \"stock_level\": 88,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1008,\n    \"product_name\": \"Insulated Lunch Bag\",\n    \"unit_price\": \"21.49\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1009,\n    \"product_name\": \"Merino Wool Beanie\",\n    \"unit_price\": \"27.00\",\n    \"stock_level\": 140,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1010,\n    \"product_name\": \"Portable Phone Charger 10000mAh\",\n    \"unit_price\": \"32.99\",\n    \"stock_level\": 64,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1011,\n    \"product_name\": \"Hiking Daypack 22L\",\n    \"unit_price\": \"64.00\",\n    \"stock_level\": 27,\n    \"is_active\": true,\n    \"category_name\": \"Outdoor\"\n  },\n  {\n    \"product_id\": 1012,\n    \"product_name\": \"Glass Food Storage Set 10-Piece\",\n    \"unit_price\": \"38.25\",\n    \"stock_level\": 52,\n    \"is_active\": true,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1013,\n    \"product_name\": \"Adjustable Dumbbell Pair 25lb\",\n    \"unit_price\": \"149.00\",\n    \"stock_level\": 9,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1014,\n    \"product_name\": \"Mechanical Keyboard Brown Switches\",\n    \"unit_price\": \"89.99\",\n    \"stock_level\": 22,\n    \"is_active\": true,\n    \"category_name\": \"Electronics\"\n  },\n  {\n    \"product_id\": 1015,\n    \"product_name\": \"Linen Throw Pillow Cover 18x18\",\n    \"unit_price\": \"16.00\",\n    \"stock_level\": 175,\n    \"is_active\": true,\n    \"category_name\": \"Home\"\n  },\n  {\n    \"product_id\": 1016,\n    \"product_name\": \"French Press Coffee Maker 1L\",\n    \"unit_price\": \"28.50\",\n    \"stock_level\": 0,\n    \"is_active\": false,\n    \"category_name\": \"Kitchen\"\n  },\n  {\n    \"product_id\": 1017,\n    \"product_name\": \"Rain Jacket Packable\",\n    \"unit_price\": \"79.00\",\n    \"stock_level\": 41,\n    \"is_active\": true,\n    \"category_name\": \"Apparel\"\n  },\n  {\n    \"product_id\": 1018,\n    \"product_name\": \"Resistance Bands Set of 5\",\n    \"unit_price\": \"19.99\",\n    \"stock_level\": 120,\n    \"is_active\": true,\n    \"category_name\": \"Fitness\"\n  },\n  {\n    \"product_id\": 1019,\n    \"product_name\": \"Monitor Stand Riser Wood\",\n    \"unit_price\": \"42.00\",\n    \"stock_level\": 36,\n    \"is_active\": true,\n    \"category_name\": \"Home Office\"\n  }\n]"
    }
   ]
  },
  {
   "id": "json_schema_fill",
   "category": "Structured output: fill a JSON schema",
   "copy_heavy": false,
   "max_tokens": 600,
   "messages": [
    {
     "role": "user",
     "content": "Extract the job posting below into JSON that conforms to this JSON Schema. Output only the JSON object.\n\nSchema:\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"title\": {\n      \"type\": \"string\"\n    },\n    \"team\": {\n      \"type\": \"string\"\n    },\n    \"location\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"city\": {\n          \"type\": \"string\"\n        },\n        \"state\": {\n          \"type\": \"string\"\n        },\n        \"work_mode\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"onsite\",\n            \"hybrid\",\n            \"remote\"\n          ]\n        },\n        \"office_days_per_week\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"tech_stack\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"min_years_experience\": {\n      \"type\": \"integer\"\n    },\n    \"required_skills\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"nice_to_have\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"salary\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"currency\": {\n          \"type\": \"string\"\n        },\n        \"min\": {\n          \"type\": \"integer\"\n        },\n        \"max\": {\n          \"type\": \"integer\"\n        },\n        \"equity\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"benefits\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"application_deadline\": {\n      \"type\": \"string\",\n      \"format\": \"date\"\n    },\n    \"hiring_manager\": {\n      \"type\": \"string\"\n    }\n  },\n  \"required\": [\n    \"title\",\n    \"location\",\n    \"salary\",\n    \"application_deadline\"\n  ]\n}\n\nPosting:\nWe're hiring a Senior Backend Engineer to join our Payments team in Austin, Texas (hybrid, 3 days a week in the office). You'll design and run the services that move about $2B a year for 40,000 small businesses. We work mostly in Go and PostgreSQL on AWS, with Kafka for event streaming. You should have at least 6 years of professional software experience, including 3+ years building distributed systems in production; experience with payment networks or PCI DSS is a plus but not required. The salary range is $185,000 to $225,000 plus equity, and we offer 401(k) matching up to 4%, full health coverage and a $2,000 annual learning budget. Applications close on November 15, 2026. The hiring manager is Jordan Ellis."
    }
   ]
  },
  {
   "id": "extract_fields",
   "category": "Extract fields from a document",
   "copy_heavy": false,
   "max_tokens": 600,
   "messages": [
    {
     "role": "user",
     "content": "Extract the following from this email as a JSON object: invoice_number, invoice_date (ISO), po_number, line_items (description, model, quantity, unit_price, line_total), subtotal, tax_rate, tax_amount, total_due, due_date (ISO), payment_method, contact_name, contact_phone. Output only JSON.\n\nFrom: billing@northwind-supplies.example\nTo: accounts.payable@contoso.example\nSubject: Invoice NW-2026-08812 for PO 45-77310\n\nHello Accounts Payable team,\n\nPlease find below the details for invoice NW-2026-08812, issued on October 1, 2026 for purchase order 45-77310.\n\nItems shipped on September 29 via Ground Freight (tracking 1Z 999 AA1 01 2345 6784):\n- 40 x Ergonomic Office Chair, model EC-200, at $189.00 each\n- 12 x Standing Desk Frame, model SD-PRO, at $310.50 each\n- 1 x Assembly service, flat fee $450.00\n\nSubtotal: $15,736.00. Sales tax (8.25%): $1,298.22. Total due: $17,034.22.\nPayment terms are Net 30, so payment is due by October 31, 2026. Please pay by ACH to account 000123456789, routing 021000021, and include the invoice number in the payment reference. A 2% late fee applies to balances outstanding after the due date.\n\nIf you have questions about this invoice, contact Maria Chen at +1 (415) 555-0143 or reply to this email.\n\nBest regards,\nNorthwind Supplies Billing\n"
    }
   ]
  },
  {
   "id": "tool_call",
   "category": "Tool call (OpenAI tools)",
   "copy_heavy": false,
   "max_tokens": 400,
   "messages": [
    {
     "role": "system",
     "content": "You are a helpful assistant with access to the user's calendar, email and contacts. The user's time zone is America/Los_Angeles and today is Monday, October 5, 2026."
    },
    {
     "role": "user",
     "content": "Put a 45 minute 'Q4 roadmap review' on my calendar next Tuesday at 10am with dana@contoso.example and li.wei@contoso.example, location Zoom https://zoom.example/j/8812, and say in the description that we'll go over the draft roadmap doc."
    }
   ],
   "tools": [
    {
     "type": "function",
     "function": {
      "name": "get_weather",
      "description": "Get the current weather and forecast for a city.",
      "parameters": {
       "type": "object",
       "properties": {
        "city": {
         "type": "string"
        },
        "days": {
         "type": "integer"
        }
       },
       "required": [
        "city"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "create_calendar_event",
      "description": "Create an event in the user's calendar.",
      "parameters": {
       "type": "object",
       "properties": {
        "title": {
         "type": "string"
        },
        "start": {
         "type": "string",
         "description": "ISO 8601 date-time with offset"
        },
        "duration_minutes": {
         "type": "integer"
        },
        "attendees": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "location": {
         "type": "string"
        },
        "description": {
         "type": "string"
        }
       },
       "required": [
        "title",
        "start",
        "duration_minutes"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "send_email",
      "description": "Send an email on behalf of the user.",
      "parameters": {
       "type": "object",
       "properties": {
        "to": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "subject": {
         "type": "string"
        },
        "body": {
         "type": "string"
        }
       },
       "required": [
        "to",
        "subject",
        "body"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "search_contacts",
      "description": "Look up a contact by name and return their email address.",
      "parameters": {
       "type": "object",
       "properties": {
        "name": {
         "type": "string"
        }
       },
       "required": [
        "name"
       ]
      }
     }
    }
   ]
  },
  {
   "id": "agent_step_8k",
   "category": "Coding-agent turn, ~8k-token context with tool results",
   "copy_heavy": true,
   "max_tokens": 800,
   "messages": [
    {
     "role": "system",
     "content": "You are a coding agent working in a local Python repository. You can call tools to read, search and edit files and to run commands. Work in small, verifiable steps: read the relevant code before changing it, make the smallest change that solves the task, keep the existing style, and do not reformat unrelated code. When you change behaviour, update docstrings to match. Prefer edit_file for small changes; use write_file only when rewriting most of a file. Never invent file contents you have not read. After editing, run the relevant tests with run_shell."
    },
    {
     "role": "user",
     "content": "In our vendored stdlib copy under vendor/, the scheduler's `enter` should reject negative delays with a ValueError instead of silently scheduling an event in the past. Also make graphlib's CycleError message include the cycle as a readable 'a -> b -> a' string. Look at the code first."
    },
    {
     "role": "assistant",
     "content": "I'll start by finding the relevant files.",
     "tool_calls": [
      {
       "id": "call_1",
       "type": "function",
       "function": {
        "name": "search",
        "arguments": "{\"pattern\": \"def enter\\\\b|class CycleError\", \"glob\": \"vendor/**/*.py\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_1",
     "content": "vendor/sched.py:78:    def enter(self, delay, priority, action, argument=(), kwargs=_sentinel):\nvendor/graphlib.py:26:class CycleError(ValueError):"
    },
    {
     "role": "assistant",
     "content": "",
     "tool_calls": [
      {
       "id": "call_2",
       "type": "function",
       "function": {
        "name": "read_file",
        "arguments": "{\"path\": \"vendor/sched.py\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_2",
     "content": "\"\"\"A generally useful event scheduler class.\n\nEach instance of this class manages its own queue.\nNo multi-threading is implied; you are supposed to hack that\nyourself, or use a single instance per application.\n\nEach instance is parametrized with two functions, one that is\nsupposed to return the current time, one that is supposed to\nimplement a delay.  You can implement real-time scheduling by\nsubstituting time and sleep from built-in module time, or you can\nimplement simulated time by writing your own functions.  This can\nalso be used to integrate scheduling with STDWIN events; the delay\nfunction is allowed to modify the queue.  Time can be expressed as\nintegers or floating-point numbers, as long as it is consistent.\n\nEvents are specified by tuples (time, priority, action, argument, kwargs).\nAs in UNIX, lower priority numbers mean higher priority; in this\nway the queue can be maintained as a priority queue.  Execution of the\nevent means calling the action function, passing it the argument\nsequence in \"argument\" (remember that in Python, multiple function\narguments are be packed in a sequence) and keyword parameters in \"kwargs\".\nThe action function may be an instance method so it\nhas another way to reference private data (besides global variables).\n\"\"\"\n\nimport time\nimport heapq\nfrom collections import namedtuple\nfrom itertools import count\nimport threading\nfrom time import monotonic as _time\n\n__all__ = [\"scheduler\"]\n\nEvent = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs')\nEvent.time.__doc__ = ('''Numeric type compatible with the return value of the\ntimefunc function passed to the constructor.''')\nEvent.priority.__doc__ = ('''Events scheduled for the same time will be executed\nin the order of their priority.''')\nEvent.sequence.__doc__ = ('''A continually increasing sequence number that\n    separates events if time and priority are equal.''')\nEvent.action.__doc__ = ('''Executing the event means executing\naction(*argument, **kwargs)''')\nEvent.argument.__doc__ = ('''argument is a sequence holding the positional\narguments for the action.''')\nEvent.kwargs.__doc__ = ('''kwargs is a dictionary holding the keyword\narguments for the action.''')\n\n_sentinel = object()\n\nclass scheduler:\n\n    def __init__(self, timefunc=_time, delayfunc=time.sleep):\n        \"\"\"Initialize a new instance, passing the time and delay\n        functions\"\"\"\n        self._queue = []\n        self._lock = threading.RLock()\n        self.timefunc = timefunc\n        self.delayfunc = delayfunc\n        self._sequence_generator = count()\n\n    def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):\n        \"\"\"Enter a new event in the queue at an absolute time.\n\n        Returns an ID for the event which can be used to remove it,\n        if necessary.\n\n        \"\"\"\n        if kwargs is _sentinel:\n            kwargs = {}\n\n        with self._lock:\n            event = Event(time, priority, next(self._sequence_generator),\n                          action, argument, kwargs)\n            heapq.heappush(self._queue, event)\n        return event # The ID\n\n    def enter(self, delay, priority, action, argument=(), kwargs=_sentinel):\n        \"\"\"A variant that specifies the time as a relative time.\n\n        This is actually the more commonly used interface.\n\n        \"\"\"\n        time = self.timefunc() + delay\n        return self.enterabs(time, priority, action, argument, kwargs)\n\n    def cancel(self, event):\n        \"\"\"Remove an event from the queue.\n\n        This must be presented the ID as returned by enter().\n        If the event is not in the queue, this raises ValueError.\n\n        \"\"\"\n        with self._lock:\n            self._queue.remove(event)\n            heapq.heapify(self._queue)\n\n    def empty(self):\n        \"\"\"Check whether the queue is empty.\"\"\"\n        with self._lock:\n            return not self._queue\n\n    def run(self, blocking=True):\n        \"\"\"Execute events until the queue is empty.\n        If blocking is False executes the scheduled events due to\n        expire soonest (if any) and then return the deadline of the\n        next scheduled call in the scheduler.\n\n        When there is a positive delay until the first event, the\n        delay function is called and the event is left in the queue;\n        otherwise, the event is removed from the queue and executed\n        (its action function is called, passing it the argument).  If\n        the delay function returns prematurely, it is simply\n        restarted.\n\n        It is legal for both the delay function and the action\n        function to modify the queue or to raise an exception;\n        exceptions are not caught but the scheduler's state remains\n        well-defined so run() may be called again.\n\n        A questionable hack is added to allow other threads to run:\n        just after an event is executed, a delay of 0 is executed, to\n        avoid monopolizing the CPU when other threads are also\n        runnable.\n\n        \"\"\"\n        # localize variable access to minimize overhead\n        # and to improve thread safety\n        lock = self._lock\n        q = self._queue\n        delayfunc = self.delayfunc\n        timefunc = self.timefunc\n        pop = heapq.heappop\n        while True:\n            with lock:\n                if not q:\n                    break\n                (time, priority, sequence, action,\n                 argument, kwargs) = q[0]\n                now = timefunc()\n                if time > now:\n                    delay = True\n                else:\n                    delay = False\n                    pop(q)\n            if delay:\n                if not blocking:\n                    return time - now\n                delayfunc(time - now)\n            else:\n                action(*argument, **kwargs)\n                delayfunc(0)   # Let other threads run\n\n    @property\n    def queue(self):\n        \"\"\"An ordered list of upcoming events.\n\n        Events are named tuples with fields for:\n            time, priority, action, arguments, kwargs\n\n        \"\"\"\n        # Use heapq to sort the queue rather than using 'sorted(self._queue)'.\n        # With heapq, two events scheduled at the same time will show in\n        # the actual order they would be retrieved.\n        with self._lock:\n            events = self._queue[:]\n        return list(map(heapq.heappop, [events]*len(events)))\n"
    },
    {
     "role": "assistant",
     "content": "",
     "tool_calls": [
      {
       "id": "call_3",
       "type": "function",
       "function": {
        "name": "read_file",
        "arguments": "{\"path\": \"vendor/graphlib.py\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_3",
     "content": "from types import GenericAlias\n\n__all__ = [\"TopologicalSorter\", \"CycleError\"]\n\n_NODE_OUT = -1\n_NODE_DONE = -2\n\n\nclass _NodeInfo:\n    __slots__ = \"node\", \"npredecessors\", \"successors\"\n\n    def __init__(self, node):\n        # The node this class is augmenting.\n        self.node = node\n\n        # Number of predecessors, generally >= 0. When this value falls to 0,\n        # and is returned by get_ready(), this is set to _NODE_OUT and when the\n        # node is marked done by a call to done(), set to _NODE_DONE.\n        self.npredecessors = 0\n\n        # List of successor nodes. The list can contain duplicated elements as\n        # long as they're all reflected in the successor's npredecessors attribute.\n        self.successors = []\n\n\nclass CycleError(ValueError):\n    \"\"\"Subclass of ValueError raised by TopologicalSorter.prepare if cycles\n    exist in the working graph.\n\n    If multiple cycles exist, only one undefined choice among them will be reported\n    and included in the exception. The detected cycle can be accessed via the second\n    element in the *args* attribute of the exception instance and consists in a list\n    of nodes, such that each node is, in the graph, an immediate predecessor of the\n    next node in the list. In the reported list, the first and the last node will be\n    the same, to make it clear that it is cyclic.\n    \"\"\"\n\n    pass\n\n\nclass TopologicalSorter:\n    \"\"\"Provides functionality to topologically sort a graph of hashable nodes\"\"\"\n\n    def __init__(self, graph=None):\n        self._node2info = {}\n        self._ready_nodes = None\n        self._npassedout = 0\n        self._nfinished = 0\n\n        if graph is not None:\n            for node, predecessors in graph.items():\n                self.add(node, *predecessors)\n\n    def _get_nodeinfo(self, node):\n        if (result := self._node2info.get(node)) is None:\n            self._node2info[node] = result = _NodeInfo(node)\n        return result\n\n    def add(self, node, *predecessors):\n        \"\"\"Add a new node and its predecessors to the graph.\n\n        Both the *node* and all elements in *predecessors* must be hashable.\n\n        If called multiple times with the same node argument, the set of dependencies\n        will be the union of all dependencies passed in.\n\n        It is possible to add a node with no dependencies (*predecessors* is not provided)\n        as well as provide a dependency twice. If a node that has not been provided before\n        is included among *predecessors* it will be automatically added to the graph with\n        no predecessors of its own.\n\n        Raises ValueError if called after \"prepare\".\n        \"\"\"\n        if self._ready_nodes is not None:\n            raise ValueError(\"Nodes cannot be added after a call to prepare()\")\n\n        # Create the node -> predecessor edges\n        nodeinfo = self._get_nodeinfo(node)\n        nodeinfo.npredecessors += len(predecessors)\n\n        # Create the predecessor -> node edges\n        for pred in predecessors:\n            pred_info = self._get_nodeinfo(pred)\n            pred_info.successors.append(node)\n\n    def prepare(self):\n        \"\"\"Mark the graph as finished and check for cycles in the graph.\n\n        If any cycle is detected, \"CycleError\" will be raised, but \"get_ready\" can\n        still be used to obtain as many nodes as possible until cycles block more\n        progress. After a call to this function, the graph cannot be modified and\n        therefore no more nodes can be added using \"add\".\n\n        Raise ValueError if nodes have already been passed out of the sorter.\n\n        \"\"\"\n        if self._npassedout > 0:\n            raise ValueError(\"cannot prepare() after starting sort\")\n\n        if self._ready_nodes is None:\n            self._ready_nodes = [\n                i.node for i in self._node2info.values() if i.npredecessors == 0\n            ]\n        # ready_nodes is set before we look for cycles on purpose:\n        # if the user wants to catch the CycleError, that's fine,\n        # they can continue using the instance to grab as many\n        # nodes as possible before cycles block more progress\n        cycle = self._find_cycle()\n        if cycle:\n            raise CycleError(\"nodes are in a cycle\", cycle)\n\n    def get_ready(self):\n        \"\"\"Return a tuple of all the nodes that are ready.\n\n        Initially it returns all nodes with no predecessors; once those are marked\n        as processed by calling \"done\", further calls will return all new nodes that\n        have all their predecessors already processed. Once no more progress can be made,\n        empty tuples are returned.\n\n        Raises ValueError if called without calling \"prepare\" previously.\n        \"\"\"\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n\n        # Get the nodes that are ready and mark them\n        result = tuple(self._ready_nodes)\n        n2i = self._node2info\n        for node in result:\n            n2i[node].npredecessors = _NODE_OUT\n\n        # Clean the list of nodes that are ready and update\n        # the counter of nodes that we have returned.\n        self._ready_nodes.clear()\n        self._npassedout += len(result)\n\n        return result\n\n    def is_active(self):\n        \"\"\"Return ``True`` if more progress can be made and ``False`` otherwise.\n\n        Progress can be made if cycles do not block the resolution and either there\n        are still nodes ready that haven't yet been returned by \"get_ready\" or the\n        number of nodes marked \"done\" is less than the number that have been returned\n        by \"get_ready\".\n\n        Raises ValueError if called without calling \"prepare\" previously.\n        \"\"\"\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n        return self._nfinished < self._npassedout or bool(self._ready_nodes)\n\n    def __bool__(self):\n        return self.is_active()\n\n    def done(self, *nodes):\n        \"\"\"Marks a set of nodes returned by \"get_ready\" as processed.\n\n        This method unblocks any successor of each node in *nodes* for being returned\n        in the future by a call to \"get_ready\".\n\n        Raises ValueError if any node in *nodes* has already been marked as\n        processed by a previous call to this method, if a node was not added to the\n        graph by using \"add\" or if called without calling \"prepare\" previously or if\n        node has not yet been returned by \"get_ready\".\n        \"\"\"\n\n        if self._ready_nodes is None:\n            raise ValueError(\"prepare() must be called first\")\n\n        n2i = self._node2info\n\n        for node in nodes:\n\n            # Check if we know about this node (it was added previously using add()\n            if (nodeinfo := n2i.get(node)) is None:\n                raise ValueError(f\"node {node!r} was not added using add()\")\n\n            # If the node has not being returned (marked as ready) previously, inform the user.\n            stat = nodeinfo.npredecessors\n            if stat != _NODE_OUT:\n                if stat >= 0:\n                    raise ValueError(\n                        f\"node {node!r} was not passed out (still not ready)\"\n                    )\n                elif stat == _NODE_DONE:\n                    raise ValueError(f\"node {node!r} was already marked done\")\n                else:\n                    assert False, f\"node {node!r}: unknown status {stat}\"\n\n            # Mark the node as processed\n            nodeinfo.npredecessors = _NODE_DONE\n\n            # Go to all the successors and reduce the number of predecessors, collecting all the ones\n            # that are ready to be returned in the next get_ready() call.\n            for successor in nodeinfo.successors:\n                successor_info = n2i[successor]\n                successor_info.npredecessors -= 1\n                if successor_info.npredecessors == 0:\n                    self._ready_nodes.append(successor)\n            self._nfinished += 1\n\n    def _find_cycle(self):\n        n2i = self._node2info\n        stack = []\n        itstack = []\n        seen = set()\n        node2stacki = {}\n\n        for node in n2i:\n            if node in seen:\n                continue\n\n            while True:\n                if node in seen:\n                    # If we have seen already the node and is in the\n                    # current stack we have found a cycle.\n                    if node in node2stacki:\n                        return stack[node2stacki[node] :] + [node]\n                    # else go on to get next successor\n                else:\n                    seen.add(node)\n                    itstack.append(iter(n2i[node].successors).__next__)\n                    node2stacki[node] = len(stack)\n                    stack.append(node)\n\n                # Backtrack to the topmost stack entry with\n                # at least another successor.\n                while stack:\n                    try:\n                        node = itstack[-1]()\n                        break\n                    except StopIteration:\n                        del node2stacki[stack.pop()]\n                        itstack.pop()\n                else:\n                    break\n        return None\n\n    def static_order(self):\n        \"\"\"Returns an iterable of nodes in a topological order.\n\n        The particular order that is returned may depend on the specific\n        order in which the items were inserted in the graph.\n\n        Using this method does not require to call \"prepare\" or \"done\". If any\n        cycle is detected, :exc:`CycleError` will be raised.\n        \"\"\"\n        self.prepare()\n        while self.is_active():\n            node_group = self.get_ready()\n            yield from node_group\n            self.done(*node_group)\n\n    __class_getitem__ = classmethod(GenericAlias)\n"
    },
    {
     "role": "assistant",
     "content": "Let me also check how the fnmatch and getopt helpers in the same package raise errors, to keep the style consistent.",
     "tool_calls": [
      {
       "id": "call_4",
       "type": "function",
       "function": {
        "name": "read_file",
        "arguments": "{\"path\": \"vendor/getopt.py\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_4",
     "content": "\"\"\"Parser for command line options.\n\nThis module helps scripts to parse the command line arguments in\nsys.argv.  It supports the same conventions as the Unix getopt()\nfunction (including the special meanings of arguments of the form '-'\nand '--').  Long options similar to those supported by GNU software\nmay be used as well via an optional third argument.  This module\nprovides two functions and an exception:\n\ngetopt() -- Parse command line options\ngnu_getopt() -- Like getopt(), but allow option and non-option arguments\nto be intermixed.\nGetoptError -- exception (class) raised with 'opt' attribute, which is the\noption involved with the exception.\n\"\"\"\n\n# Long option support added by Lars Wirzenius <liw@iki.fi>.\n#\n# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions\n# to class-based exceptions.\n#\n# Peter Åstrand <astrand@lysator.liu.se> added gnu_getopt().\n#\n# TODO for gnu_getopt():\n#\n# - GNU getopt_long_only mechanism\n# - an option string with a W followed by semicolon should\n#   treat \"-W foo\" as \"--foo\"\n\n__all__ = [\"GetoptError\",\"error\",\"getopt\",\"gnu_getopt\"]\n\nimport os\nfrom gettext import gettext as _\n\n\nclass GetoptError(Exception):\n    opt = ''\n    msg = ''\n    def __init__(self, msg, opt=''):\n        self.msg = msg\n        self.opt = opt\n        Exception.__init__(self, msg, opt)\n\n    def __str__(self):\n        return self.msg\n\nerror = GetoptError # backward compatibility\n\ndef getopt(args, shortopts, longopts = []):\n    \"\"\"getopt(args, options[, long_options]) -> opts, args\n\n    Parses command line options and parameter list.  args is the\n    argument list to be parsed, without the leading reference to the\n    running program.  Typically, this means \"sys.argv[1:]\".  shortopts\n    is the string of option letters that the script wants to\n    recognize, with options that require an argument followed by a\n    colon and options that accept an optional argument followed by\n    two colons (i.e., the same format that Unix getopt() uses).  If\n    specified, longopts is a list of strings with the names of the\n    long options which should be supported.  The leading '--'\n    characters should not be included in the option name.  Options\n    which require an argument should be followed by an equal sign\n    ('=').  Options which accept an optional argument should be\n    followed by an equal sign and question mark ('=?').\n\n    The return value consists of two elements: the first is a list of\n    (option, value) pairs; the second is the list of program arguments\n    left after the option list was stripped (this is a trailing slice\n    of the first argument).  Each option-and-value pair returned has\n    the option as its first element, prefixed with a hyphen (e.g.,\n    '-x'), and the option argument as its second element, or an empty\n    string if the option has no argument.  The options occur in the\n    list in the same order in which they were found, thus allowing\n    multiple occurrences.  Long and short options may be mixed.\n\n    \"\"\"\n\n    opts = []\n    if isinstance(longopts, str):\n        longopts = [longopts]\n    else:\n        longopts = list(longopts)\n    while args and args[0].startswith('-') and args[0] != '-':\n        if args[0] == '--':\n            args = args[1:]\n            break\n        if args[0].startswith('--'):\n            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])\n        else:\n            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])\n\n    return opts, args\n\ndef gnu_getopt(args, shortopts, longopts = []):\n    \"\"\"getopt(args, options[, long_options]) -> opts, args\n\n    This function works like getopt(), except that GNU style scanning\n    mode is used by default. This means that option and non-option\n    arguments may be intermixed. The getopt() function stops\n    processing options as soon as a non-option argument is\n    encountered.\n\n    If the first character of the option string is '+', or if the\n    environment variable POSIXLY_CORRECT is set, then option\n    processing stops as soon as a non-option argument is encountered.\n\n    \"\"\"\n\n    opts = []\n    prog_args = []\n    if isinstance(longopts, str):\n        longopts = [longopts]\n    else:\n        longopts = list(longopts)\n\n    return_in_order = False\n    if shortopts.startswith('-'):\n        shortopts = shortopts[1:]\n        all_options_first = False\n        return_in_order = True\n    # Allow options after non-option arguments?\n    elif shortopts.startswith('+'):\n        shortopts = shortopts[1:]\n        all_options_first = True\n    elif os.environ.get(\"POSIXLY_CORRECT\"):\n        all_options_first = True\n    else:\n        all_options_first = False\n\n    while args:\n        if args[0] == '--':\n            prog_args += args[1:]\n            break\n\n        if args[0][:2] == '--':\n            if return_in_order and prog_args:\n                opts.append((None, prog_args))\n                prog_args = []\n            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])\n        elif args[0][:1] == '-' and args[0] != '-':\n            if return_in_order and prog_args:\n                opts.append((None, prog_args))\n                prog_args = []\n            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])\n        else:\n            if all_options_first:\n                prog_args += args\n                break\n            else:\n                prog_args.append(args[0])\n                args = args[1:]\n\n    return opts, prog_args\n\ndef do_longs(opts, opt, longopts, args):\n    try:\n        i = opt.index('=')\n    except ValueError:\n        optarg = None\n    else:\n        opt, optarg = opt[:i], opt[i+1:]\n\n    has_arg, opt = long_has_args(opt, longopts)\n    if has_arg:\n        if optarg is None and has_arg != '?':\n            if not args:\n                raise GetoptError(_('option --%s requires argument') % opt, opt)\n            optarg, args = args[0], args[1:]\n    elif optarg is not None:\n        raise GetoptError(_('option --%s must not have an argument') % opt, opt)\n    opts.append(('--' + opt, optarg or ''))\n    return opts, args\n\n# Return:\n#   has_arg?\n#   full option name\ndef long_has_args(opt, longopts):\n    possibilities = [o for o in longopts if o.startswith(opt)]\n    if not possibilities:\n        raise GetoptError(_('option --%s not recognized') % opt, opt)\n    # Is there an exact match?\n    if opt in possibilities:\n        return False, opt\n    elif opt + '=' in possibilities:\n        return True, opt\n    elif opt + '=?' in possibilities:\n        return '?', opt\n    # Possibilities must be unique to be accepted\n    if len(possibilities) > 1:\n        raise GetoptError(\n            _(\"option --%s not a unique prefix; possible options: %s\")\n            % (opt, \", \".join(possibilities)),\n            opt,\n        )\n    assert len(possibilities) == 1\n    unique_match = possibilities[0]\n    if unique_match.endswith('=?'):\n        return '?', unique_match[:-2]\n    has_arg = unique_match.endswith('=')\n    if has_arg:\n        unique_match = unique_match[:-1]\n    return has_arg, unique_match\n\ndef do_shorts(opts, optstring, shortopts, args):\n    while optstring != '':\n        opt, optstring = optstring[0], optstring[1:]\n        has_arg = short_has_arg(opt, shortopts)\n        if has_arg:\n            if optstring == '' and has_arg != '?':\n                if not args:\n                    raise GetoptError(_('option -%s requires argument') % opt,\n                                      opt)\n                optstring, args = args[0], args[1:]\n            optarg, optstring = optstring, ''\n        else:\n            optarg = ''\n        opts.append(('-' + opt, optarg))\n    return opts, args\n\ndef short_has_arg(opt, shortopts):\n    for i in range(len(shortopts)):\n        if opt == shortopts[i] != ':':\n            if not shortopts.startswith(':', i+1):\n                return False\n            if shortopts.startswith('::', i+1):\n                return '?'\n            return True\n    raise GetoptError(_('option -%s not recognized') % opt, opt)\n\nif __name__ == '__main__':\n    import sys\n    print(getopt(sys.argv[1:], \"a:b\", [\"alpha=\", \"beta\"]))\n"
    },
    {
     "role": "assistant",
     "content": "",
     "tool_calls": [
      {
       "id": "call_5",
       "type": "function",
       "function": {
        "name": "read_file",
        "arguments": "{\"path\": \"vendor/fnmatch.py\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_5",
     "content": "\"\"\"Filename matching with shell patterns.\n\nfnmatch(FILENAME, PATTERN) matches according to the local convention.\nfnmatchcase(FILENAME, PATTERN) always takes case in account.\n\nThe functions operate by translating the pattern into a regular\nexpression.  They cache the compiled regular expressions for speed.\n\nThe function translate(PATTERN) returns a regular expression\ncorresponding to PATTERN.  (It does not compile it.)\n\"\"\"\n\nimport functools\nimport itertools\nimport os\nimport posixpath\nimport re\n\n__all__ = [\"filter\", \"filterfalse\", \"fnmatch\", \"fnmatchcase\", \"translate\"]\n\n\ndef fnmatch(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN.\n\n    Patterns are Unix shell style:\n\n    *       matches everything\n    ?       matches any single character\n    [seq]   matches any character in seq\n    [!seq]  matches any char not in seq\n\n    An initial period in FILENAME is not special.\n    Both FILENAME and PATTERN are first case-normalized\n    if the operating system requires it.\n    If you don't want this, use fnmatchcase(FILENAME, PATTERN).\n    \"\"\"\n    name = os.path.normcase(name)\n    pat = os.path.normcase(pat)\n    return fnmatchcase(name, pat)\n\n\n@functools.lru_cache(maxsize=32768, typed=True)\ndef _compile_pattern(pat):\n    if isinstance(pat, bytes):\n        pat_str = str(pat, 'ISO-8859-1')\n        res_str = translate(pat_str)\n        res = bytes(res_str, 'ISO-8859-1')\n    else:\n        res = translate(pat)\n    return re.compile(res).match\n\n\ndef filter(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that match PAT.\"\"\"\n    result = []\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        for name in names:\n            if match(name):\n                result.append(name)\n    else:\n        for name in names:\n            if match(os.path.normcase(name)):\n                result.append(name)\n    return result\n\n\ndef filterfalse(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that do not match PAT.\"\"\"\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        return list(itertools.filterfalse(match, names))\n\n    result = []\n    for name in names:\n        if match(os.path.normcase(name)) is None:\n            result.append(name)\n    return result\n\n\ndef fnmatchcase(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN, including case.\n\n    This is a version of fnmatch() which doesn't case-normalize\n    its arguments.\n    \"\"\"\n    match = _compile_pattern(pat)\n    return match(name) is not None\n\n\ndef translate(pat):\n    \"\"\"Translate a shell PATTERN to a regular expression.\n\n    There is no way to quote meta-characters.\n    \"\"\"\n\n    parts, star_indices = _translate(pat, '*', '.')\n    return _join_translated_parts(parts, star_indices)\n\n\n_re_setops_sub = re.compile(r'([&~|])').sub\n_re_escape = functools.lru_cache(maxsize=512)(re.escape)\n\n\ndef _translate(pat, star, question_mark):\n    res = []\n    add = res.append\n    star_indices = []\n\n    i, n = 0, len(pat)\n    while i < n:\n        c = pat[i]\n        i = i+1\n        if c == '*':\n            # store the position of the wildcard\n            star_indices.append(len(res))\n            add(star)\n            # compress consecutive `*` into one\n            while i < n and pat[i] == '*':\n                i += 1\n        elif c == '?':\n            add(question_mark)\n        elif c == '[':\n            j = i\n            if j < n and pat[j] == '!':\n                j = j+1\n            if j < n and pat[j] == ']':\n                j = j+1\n            while j < n and pat[j] != ']':\n                j = j+1\n            if j >= n:\n                add('\\\\[')\n            else:\n                stuff = pat[i:j]\n                if '-' not in stuff:\n                    stuff = stuff.replace('\\\\', r'\\\\')\n                else:\n                    chunks = []\n                    k = i+2 if pat[i] == '!' else i+1\n                    while True:\n                        k = pat.find('-', k, j)\n                        if k < 0:\n                            break\n                        chunks.append(pat[i:k])\n                        i = k+1\n                        k = k+3\n                    chunk = pat[i:j]\n                    if chunk:\n                        chunks.append(chunk)\n                    else:\n                        chunks[-1] += '-'\n                    # Remove empty ranges -- invalid in RE.\n                    for k in range(len(chunks)-1, 0, -1):\n                        if chunks[k-1][-1] > chunks[k][0]:\n                            chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]\n                            del chunks[k]\n                    # Escape backslashes and hyphens for set difference (--).\n                    # Hyphens that create ranges shouldn't be escaped.\n                    stuff = '-'.join(s.replace('\\\\', r'\\\\').replace('-', r'\\-')\n                                     for s in chunks)\n                i = j+1\n                if not stuff:\n                    # Empty range: never match.\n                    add('(?!)')\n                elif stuff == '!':\n                    # Negated empty range: match any character.\n                    add('.')\n                else:\n                    # Escape set operations (&&, ~~ and ||).\n                    stuff = _re_setops_sub(r'\\\\\\1', stuff)\n                    if stuff[0] == '!':\n                        stuff = '^' + stuff[1:]\n                    elif stuff[0] in ('^', '['):\n                        stuff = '\\\\' + stuff\n                    add(f'[{stuff}]')\n        else:\n            add(_re_escape(c))\n    assert i == n\n    return res, star_indices\n\n\ndef _join_translated_parts(parts, star_indices):\n    if not star_indices:\n        return fr'(?s:{\"\".join(parts)})\\z'\n    iter_star_indices = iter(star_indices)\n    j = next(iter_star_indices)\n    buffer = parts[:j]  # fixed pieces at the start\n    append, extend = buffer.append, buffer.extend\n    i = j + 1\n    for j in iter_star_indices:\n        # Now deal with STAR fixed STAR fixed ...\n        # For an interior `STAR fixed` pairing, we want to do a minimal\n        # .*? match followed by `fixed`, with no possibility of backtracking.\n        # Atomic groups (\"(?>...)\") allow us to spell that directly.\n        # Note: people rely on the undocumented ability to join multiple\n        # translate() results together via \"|\" to build large regexps matching\n        # \"one of many\" shell patterns.\n        append('(?>.*?')\n        extend(parts[i:j])\n        append(')')\n        i = j + 1\n    append('.*')\n    extend(parts[i:])\n    res = ''.join(buffer)\n    return fr'(?s:{res})\\z'\n"
    },
    {
     "role": "assistant",
     "content": "",
     "tool_calls": [
      {
       "id": "call_6",
       "type": "function",
       "function": {
        "name": "run_shell",
        "arguments": "{\"command\": \"python -m pytest tests/test_vendor_sched.py tests/test_vendor_graphlib.py -q\"}"
       }
      }
     ]
    },
    {
     "role": "tool",
     "tool_call_id": "call_6",
     "content": "........................                                             [100%]\n24 passed in 0.41s"
    },
    {
     "role": "user",
     "content": "Good, tests pass on the current code. Now make the sched.py change first. Use edit_file."
    }
   ],
   "tools": [
    {
     "type": "function",
     "function": {
      "name": "read_file",
      "description": "Read a file from the repository and return its contents.",
      "parameters": {
       "type": "object",
       "properties": {
        "path": {
         "type": "string",
         "description": "Path relative to the repository root."
        }
       },
       "required": [
        "path"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "edit_file",
      "description": "Replace an exact string in a file with a new string. old_string must match the file exactly and be unique.",
      "parameters": {
       "type": "object",
       "properties": {
        "path": {
         "type": "string"
        },
        "old_string": {
         "type": "string"
        },
        "new_string": {
         "type": "string"
        }
       },
       "required": [
        "path",
        "old_string",
        "new_string"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "write_file",
      "description": "Write the complete contents of a file, replacing it if it exists.",
      "parameters": {
       "type": "object",
       "properties": {
        "path": {
         "type": "string"
        },
        "content": {
         "type": "string"
        }
       },
       "required": [
        "path",
        "content"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "run_shell",
      "description": "Run a shell command in the repository root and return stdout, stderr and the exit code.",
      "parameters": {
       "type": "object",
       "properties": {
        "command": {
         "type": "string"
        },
        "timeout_s": {
         "type": "integer"
        }
       },
       "required": [
        "command"
       ]
      }
     }
    },
    {
     "type": "function",
     "function": {
      "name": "search",
      "description": "Search the repository for a regular expression and return matching lines with file names and line numbers.",
      "parameters": {
       "type": "object",
       "properties": {
        "pattern": {
         "type": "string"
        },
        "glob": {
         "type": "string"
        }
       },
       "required": [
        "pattern"
       ]
      }
     }
    }
   ]
  },
  {
   "id": "summarize",
   "category": "Summarize an article",
   "copy_heavy": false,
   "max_tokens": 500,
   "messages": [
    {
     "role": "user",
     "content": "Summarize this news article in 5 bullet points for a busy reader, then give one sentence on what happens next.\n\nCity Council Approves Downtown Protected Bike Lane Network After Two-Year Debate\n\nAfter more than two years of public meetings, traffic studies and occasionally heated testimony, the Riverton City Council voted 6-3 on Tuesday night to approve a 14-mile network of protected bike lanes across the downtown core. Construction on the first phase, which covers Main Street, Fifth Avenue and the riverfront corridor, is scheduled to begin in March and finish before the end of next year.\n\nThe plan replaces painted bike lanes on eight streets with lanes separated from traffic by concrete curbs or planters, adds bicycle signals at 23 intersections, and converts two one-way streets back to two-way traffic. City engineers estimate the total cost at $41 million, of which $26 million will come from a federal transportation grant awarded last spring. The remaining $15 million will be drawn from the city's capital improvement budget over four years.\n\nSupporters argued that the network is overdue. The city recorded 212 crashes involving cyclists in the past three years, eleven of them resulting in serious injuries, and most occurred on streets with painted lanes only. \"Paint is not protection,\" said council member Alicia Moreno, who sponsored the measure. \"Every family that has told me they would ride if they felt safe is the reason this passed.\"\n\nOpponents focused on parking and deliveries. The plan removes about 340 of the roughly 2,900 on-street parking spaces downtown, and several business owners on Fifth Avenue said they feared losing customers who drive in from the suburbs. \"We are not against bikes,\" said Tom Hadley, who has run a hardware store on Fifth for 31 years. \"We are against losing the spaces right in front of our doors.\" In response, the council added an amendment requiring the city to create 150 short-term loading and pickup zones and to open the municipal garage on Third Street free for the first hour on weekdays.\n\nThe city's own traffic analysis, completed in August by an outside consulting firm, projected that average car travel times through downtown would increase by less than 40 seconds at peak hours, while bicycle trips could triple within five years based on results in comparable mid-sized cities. Council member Greg Patterson, who voted against the plan, questioned those projections, noting that the consultant's comparison cities have milder winters. \"Riverton gets four months of snow,\" he said. \"I would like to see the ridership numbers from February, not from June.\"\n\nTransit advocates welcomed the vote but pressed the city to coordinate the work with the bus network redesign that begins next year. Three of the streets in the plan are also major bus routes, and the transit agency has asked for floating bus stops so that buses do not have to cross the bike lanes to reach the curb. The city's transportation director, Priya Raman, said floating stops are included in the design for Main Street and will be evaluated for the other two routes during the engineering phase.\n\nThe vote also sets up a public reporting requirement. The transportation department must publish quarterly data on crashes, bike counts, parking occupancy and business license renewals in the affected corridors for five years after construction. Moreno said the data will settle the arguments either way. \"If we are wrong, we will see it in the numbers, and we will fix it,\" she said.\n\nResidents will have one more chance to weigh in on the details. Design workshops for each of the three phase-one corridors are scheduled for November, and the final engineering drawings will be posted for a 30-day comment period in January before construction contracts are awarded.\n"
    }
   ]
  },
  {
   "id": "translate",
   "category": "Translate (English to Spanish)",
   "copy_heavy": false,
   "max_tokens": 500,
   "messages": [
    {
     "role": "user",
     "content": "Translate this customer-support reply into Spanish (Spain). Keep the amounts, dates and card digits unchanged. Output only the translation.\n\nThank you for contacting our support team. We have reviewed your account and confirmed that the duplicate charge on September 28 was caused by a temporary error in our payment system. The second charge of $49.00 has been refunded to the card ending in 4417, and you should see the refund on your statement within five to seven business days, depending on your bank. Your subscription remains active and your next billing date is unchanged. We have also added a one-month credit to your account as an apology for the inconvenience. If the refund does not appear within ten business days, please reply to this email with a screenshot of your statement and we will investigate further with our payment provider. We appreciate your patience and your continued trust in our service."
    }
   ]
  },
  {
   "id": "proofread_doc",
   "category": "Proofread a document, return full text",
   "copy_heavy": true,
   "max_tokens": 1000,
   "messages": [
    {
     "role": "user",
     "content": "Fix the spelling mistakes in this README. Do not change anything else (keep the Markdown, code and wording exactly). Output only the corrected README.\n\n# quickcsv\n\nquickcsv is a small, dependancy-free library for reading and writing CSV files in Python. It was writen because the standard library's csv module is powerfull but verbose for the comon case of loading a file into a list of dictionarys and writing it back.\n\n## Instalation\n\nInstall from PyPI with pip:\n\n    pip install quickcsv\n\nquickcsv supports Python 3.9 and newer and has no runtime dependancies.\n\n## Usage\n\nTo load a file, call `quickcsv.load` with a path. The first row is treated as the header and every following row becomes a dictionary keyed by the header names:\n\n    import quickcsv\n    rows = quickcsv.load(\"orders.csv\")\n    print(rows[0][\"customer\"])\n\nBy default all values are returned as strings. Pass `types=` to convert columns as they are read, for example `types={\"quantity\": int, \"price\": float}`. Columns that are not listed are left as strings, and a value that fails to convert raises `quickcsv.ConversionError` with the row number and column name so that you can find the problem quickly.\n\nTo write rows back, call `quickcsv.dump` with a list of dictionarys and a path. The header is taken from the keys of the first row unless you pass `fields=` explicitly. Existing files are overwriten, so pass `mode=\"a\"` if you want to append to a file instead.\n\n## Large files\n\nFor files that do not fit comfortably in memmory, use `quickcsv.iter_rows`, which yields one dictionary at a time and never loads the whole file. It accepts the same `types=` argument as `load`. Writing large files is handled by `quickcsv.Writer`, a context manager that writes each row as soon as you add it.\n\n## Contributing\n\nBug reports and pull requests are welcome. Please run the test suite with `pytest` before submiting a pull request and add a test for any bug you fix. We try to keep the libary small, so new features should be discused in an issue first.\n\n## License\n\nquickcsv is released under the MIT license.\n"
    }
   ]
  },
  {
   "id": "write_email",
   "category": "Write an email",
   "copy_heavy": false,
   "max_tokens": 500,
   "messages": [
    {
     "role": "user",
     "content": "Write a short, friendly email to my team: the Friday release is moving to next Wednesday because the payment provider's sandbox is down; QA keeps testing on staging; the customer webinar on Thursday still happens; and I'll send an updated checklist tomorrow morning. Sign it Sam."
    }
   ]
  },
  {
   "id": "story",
   "category": "Free-form prose (short story)",
   "copy_heavy": false,
   "max_tokens": 800,
   "messages": [
    {
     "role": "user",
     "content": "Write a short story (about 450 words) about a lighthouse keeper who receives a letter addressed to someone who lived in the lighthouse a hundred years ago."
    }
   ]
  },
  {
   "id": "explain_code",
   "category": "Explain code",
   "copy_heavy": false,
   "max_tokens": 700,
   "messages": [
    {
     "role": "user",
     "content": "Explain what `_translate` and `_join_translated_parts` do in this module, step by step, for a developer who has never read it. Mention why consecutive `*` are collapsed.\n\n```python\n\"\"\"Filename matching with shell patterns.\n\nfnmatch(FILENAME, PATTERN) matches according to the local convention.\nfnmatchcase(FILENAME, PATTERN) always takes case in account.\n\nThe functions operate by translating the pattern into a regular\nexpression.  They cache the compiled regular expressions for speed.\n\nThe function translate(PATTERN) returns a regular expression\ncorresponding to PATTERN.  (It does not compile it.)\n\"\"\"\n\nimport functools\nimport itertools\nimport os\nimport posixpath\nimport re\n\n__all__ = [\"filter\", \"filterfalse\", \"fnmatch\", \"fnmatchcase\", \"translate\"]\n\n\ndef fnmatch(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN.\n\n    Patterns are Unix shell style:\n\n    *       matches everything\n    ?       matches any single character\n    [seq]   matches any character in seq\n    [!seq]  matches any char not in seq\n\n    An initial period in FILENAME is not special.\n    Both FILENAME and PATTERN are first case-normalized\n    if the operating system requires it.\n    If you don't want this, use fnmatchcase(FILENAME, PATTERN).\n    \"\"\"\n    name = os.path.normcase(name)\n    pat = os.path.normcase(pat)\n    return fnmatchcase(name, pat)\n\n\n@functools.lru_cache(maxsize=32768, typed=True)\ndef _compile_pattern(pat):\n    if isinstance(pat, bytes):\n        pat_str = str(pat, 'ISO-8859-1')\n        res_str = translate(pat_str)\n        res = bytes(res_str, 'ISO-8859-1')\n    else:\n        res = translate(pat)\n    return re.compile(res).match\n\n\ndef filter(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that match PAT.\"\"\"\n    result = []\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        for name in names:\n            if match(name):\n                result.append(name)\n    else:\n        for name in names:\n            if match(os.path.normcase(name)):\n                result.append(name)\n    return result\n\n\ndef filterfalse(names, pat):\n    \"\"\"Construct a list from those elements of the iterable NAMES that do not match PAT.\"\"\"\n    pat = os.path.normcase(pat)\n    match = _compile_pattern(pat)\n    if os.path is posixpath:\n        # normcase on posix is NOP. Optimize it away from the loop.\n        return list(itertools.filterfalse(match, names))\n\n    result = []\n    for name in names:\n        if match(os.path.normcase(name)) is None:\n            result.append(name)\n    return result\n\n\ndef fnmatchcase(name, pat):\n    \"\"\"Test whether FILENAME matches PATTERN, including case.\n\n    This is a version of fnmatch() which doesn't case-normalize\n    its arguments.\n    \"\"\"\n    match = _compile_pattern(pat)\n    return match(name) is not None\n\n\ndef translate(pat):\n    \"\"\"Translate a shell PATTERN to a regular expression.\n\n    There is no way to quote meta-characters.\n    \"\"\"\n\n    parts, star_indices = _translate(pat, '*', '.')\n    return _join_translated_parts(parts, star_indices)\n\n\n_re_setops_sub = re.compile(r'([&~|])').sub\n_re_escape = functools.lru_cache(maxsize=512)(re.escape)\n\n\ndef _translate(pat, star, question_mark):\n    res = []\n    add = res.append\n    star_indices = []\n\n    i, n = 0, len(pat)\n    while i < n:\n        c = pat[i]\n        i = i+1\n        if c == '*':\n            # store the position of the wildcard\n            star_indices.append(len(res))\n            add(star)\n            # compress consecutive `*` into one\n            while i < n and pat[i] == '*':\n                i += 1\n        elif c == '?':\n            add(question_mark)\n        elif c == '[':\n            j = i\n            if j < n and pat[j] == '!':\n                j = j+1\n            if j < n and pat[j] == ']':\n                j = j+1\n            while j < n and pat[j] != ']':\n                j = j+1\n            if j >= n:\n                add('\\\\[')\n            else:\n                stuff = pat[i:j]\n                if '-' not in stuff:\n                    stuff = stuff.replace('\\\\', r'\\\\')\n                else:\n                    chunks = []\n                    k = i+2 if pat[i] == '!' else i+1\n                    while True:\n                        k = pat.find('-', k, j)\n                        if k < 0:\n                            break\n                        chunks.append(pat[i:k])\n                        i = k+1\n                        k = k+3\n                    chunk = pat[i:j]\n                    if chunk:\n                        chunks.append(chunk)\n                    else:\n                        chunks[-1] += '-'\n                    # Remove empty ranges -- invalid in RE.\n                    for k in range(len(chunks)-1, 0, -1):\n                        if chunks[k-1][-1] > chunks[k][0]:\n                            chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]\n                            del chunks[k]\n                    # Escape backslashes and hyphens for set difference (--).\n                    # Hyphens that create ranges shouldn't be escaped.\n                    stuff = '-'.join(s.replace('\\\\', r'\\\\').replace('-', r'\\-')\n                                     for s in chunks)\n                i = j+1\n                if not stuff:\n                    # Empty range: never match.\n                    add('(?!)')\n                elif stuff == '!':\n                    # Negated empty range: match any character.\n                    add('.')\n                else:\n                    # Escape set operations (&&, ~~ and ||).\n                    stuff = _re_setops_sub(r'\\\\\\1', stuff)\n                    if stuff[0] == '!':\n                        stuff = '^' + stuff[1:]\n                    elif stuff[0] in ('^', '['):\n                        stuff = '\\\\' + stuff\n                    add(f'[{stuff}]')\n        else:\n            add(_re_escape(c))\n    assert i == n\n    return res, star_indices\n\n\ndef _join_translated_parts(parts, star_indices):\n    if not star_indices:\n        return fr'(?s:{\"\".join(parts)})\\z'\n    iter_star_indices = iter(star_indices)\n    j = next(iter_star_indices)\n    buffer = parts[:j]  # fixed pieces at the start\n    append, extend = buffer.append, buffer.extend\n    i = j + 1\n    for j in iter_star_indices:\n        # Now deal with STAR fixed STAR fixed ...\n        # For an interior `STAR fixed` pairing, we want to do a minimal\n        # .*? match followed by `fixed`, with no possibility of backtracking.\n        # Atomic groups (\"(?>...)\") allow us to spell that directly.\n        # Note: people rely on the undocumented ability to join multiple\n        # translate() results together via \"|\" to build large regexps matching\n        # \"one of many\" shell patterns.\n        append('(?>.*?')\n        extend(parts[i:j])\n        append(')')\n        i = j + 1\n    append('.*')\n    extend(parts[i:])\n    res = ''.join(buffer)\n    return fr'(?s:{res})\\z'\n```"
    }
   ]
  },
  {
   "id": "sql",
   "category": "SQL",
   "copy_heavy": false,
   "max_tokens": 450,
   "messages": [
    {
     "role": "user",
     "content": "Given this PostgreSQL schema, write a query that returns, for each product category, the total revenue and the number of distinct customers from orders with status 'completed' placed in the last 90 days, only for categories with revenue above 10000, sorted by revenue descending. Briefly explain the query after it.\n\nCREATE TABLE customers (id BIGINT PRIMARY KEY, name TEXT NOT NULL, country TEXT, created_at TIMESTAMP NOT NULL);\nCREATE TABLE orders (id BIGINT PRIMARY KEY, customer_id BIGINT REFERENCES customers(id), status TEXT NOT NULL, created_at TIMESTAMP NOT NULL);\nCREATE TABLE order_items (order_id BIGINT REFERENCES orders(id), product_id BIGINT, quantity INT NOT NULL, unit_price NUMERIC(10,2) NOT NULL);\nCREATE TABLE products (id BIGINT PRIMARY KEY, name TEXT NOT NULL, category TEXT NOT NULL);\n"
    }
   ]
  },
  {
   "id": "regex",
   "category": "Regex",
   "copy_heavy": false,
   "max_tokens": 450,
   "messages": [
    {
     "role": "user",
     "content": "Write a Python regular expression that matches semantic version strings like 1.2.3, 10.0.0-rc.1 and 2.4.0+build.7 but not 01.2.3 or 1.2. Show the pattern, a short explanation of each part, and a few test cases with re.fullmatch."
    }
   ]
  },
  {
   "id": "markdown_table",
   "category": "Markdown table from notes",
   "copy_heavy": true,
   "max_tokens": 700,
   "messages": [
    {
     "role": "user",
     "content": "Turn these notes into a Markdown table with columns Region, Q3 revenue, Q2 revenue, QoQ change (%), New customers, Churn, Top product. Compute QoQ change to one decimal place. Then add a one-sentence takeaway.\n\nQ3 regional results, from the weekly sync notes:\nNorth: revenue 4.2M (Q2 was 3.9M), 118 new customers, churn 2.1%, top product Atlas Pro.\nSouth: revenue 3.1M (Q2 3.4M), 76 new customers, churn 3.8%, top product Atlas Lite.\nEast: revenue 5.6M (Q2 5.0M), 141 new customers, churn 1.7%, top product Atlas Pro.\nWest: revenue 4.8M (Q2 4.9M), 102 new customers, churn 2.6%, top product Beacon.\nCentral: revenue 2.3M (Q2 2.0M), 58 new customers, churn 2.9%, top product Atlas Lite.\nInternational: revenue 3.7M (Q2 3.1M), 95 new customers, churn 2.2%, top product Beacon.\n"
    }
   ]
  },
  {
   "id": "long_answer",
   "category": "Long technical answer (~800 tokens)",
   "copy_heavy": false,
   "max_tokens": 1100,
   "messages": [
    {
     "role": "user",
     "content": "Explain how a B-tree index works in a relational database: structure, search, insert with node splits, why it suits disks and SSDs, and how it compares with a hash index and an LSM tree. Aim for about 600 words with headings."
    }
   ]
  }
 ]
}