oc_chat
Loading...
Searching...
No Matches
work_queue_manage.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# oc_chat/scripts/work_queue_manage.py
4
5# OCT-LINT: disable=tests_exist reason="Wiring shim; covered by oc_chat/tests/unit/test_271_queue_shims.py"
6"""
7The queue's operator surface — moved to :mod:`oc_orchestrator.work_queue_manage`.
8
9Purpose
10-------
11Plan 271 P3. The CLI now lives in the standalone ``oc_orchestrator``
12package. This file keeps ``oc_chat.scripts.work_queue_manage`` working —
13the path ``MULTI_AGENT_WORKFLOW.md`` §6.1 and every orchestrator command
14have always named — and supplies the two defaults that are oc_chat's and
15not the package's:
16
17- **the program name.** ``--help`` must print exactly what it printed
18 before the split, and ``prog`` is the only line in it that could differ.
19- **the registry backend.** The package declares ``--backend registry``
20 as a plugin point and holds no registry to fill it; oc_chat has one, so
21 this is where the factory is built. ``--backend registry`` therefore
22 behaves byte for byte as it did before the split, and the four lazy
23 registry imports that used to sit inside the package's
24 ``_build_backend`` sit here instead — which is precisely the seam the
25 plan-258 receipt modelled as a named ``--cut``.
26
27Unlike the two ``core/`` queue shims this module is NOT a rebinding,
28because it has behaviour of its own: those two defaults. Every other name
29is delegated by :func:`__getattr__`.
30
31Responsibilities
32----------------
33- :func:`main` — the package's CLI with oc_chat's ``prog`` and factory.
34- :func:`_registry_backend` — the registry arm, verbatim from the pre-271
35 module's ``_build_backend``.
36- :func:`__getattr__` — every other name, delegated unchanged.
37
38Diagnostics
39-----------
40Domain: OC_CHAT.MAIN
41Levels:
42 L2 - lifecycle events (which backend was built)
43 L3 - semantic details
44 L4 - deep tracing (delegated name lookups)
45
46Contracts
47---------
48- Output is byte-identical to the pre-271 module for every sub-command,
49 and so are the rows a registry-mode round trip lands in the registry.
50- The registry imports stay LAZY, inside the factory: the file backend is
51 the default, and a ``work_queue_manage list`` against it must not drag
52 the registry's auth, signing and checkpoint stack into the process.
53- Retirement rule (plan 271 P3): this path stays until an explicit
54 retirement plan retargets the workflow doc. New code names
55 ``oc_orchestrator.work_queue_manage`` directly.
56
57Dependencies
58------------
59- oc_diagnostics (structured debug logging via _dbg)
60- oc_orchestrator.work_queue_manage (the moved module this path wraps)
61- oc_chat.registry (lazy; Registry, which wraps the storage the registry queue backend writes to)
62- oc_orchestrator.work_queue (QueueBackend, the factory's return type, and QueueBackendError, raised when no operator slot is active)
63- oc_chat.registry.backends.sqlite (lazy; SQLiteBackend, the registry storage and its active operator slot)
64- oc_chat.registry.discovery (lazy; discover_registry_location, which finds the registry file)
65- oc_chat.registry.queue_backend (lazy; RegistryQueueBackend, the registry-backed queue the factory returns)
66"""
67
68from __future__ import annotations
69
70import argparse
71import sys
72from typing import Any
73
74from oc_diagnostics import _dbg
75
76from oc_orchestrator import work_queue_manage as _moved
77from oc_orchestrator.work_queue import QueueBackend, QueueBackendError
78
79#: The program name this path has always printed in ``--help``.
80PROG = "python -m oc_chat.scripts.work_queue_manage"
81
82_dbg(
83 "OC_CHAT.MAIN",
84 "module",
85 "work_queue_manage shim -> oc_orchestrator.work_queue_manage",
86 4,
87)
88
89
90def __getattr__(name: str) -> Any:
91 """Delegate every name this shim does not define to the moved module."""
92 return getattr(_moved, name)
93
94
95def _registry_backend(args: argparse.Namespace) -> QueueBackend:
96 """Build the registry-backed queue (plan 271 P2's consumer factory).
97
98 Lifted verbatim from the registry arm of the pre-271
99 ``work_queue_manage._build_backend``. The package declares the seam
100 and names no registry; this is the consumer that fills it, so the
101 four imports the plan-258 receipt cut as a named edge now live on
102 oc_chat's side of the split, where they always belonged.
103
104 Raises:
105 QueueBackendError: EXTERNAL_ERROR (L2 for the caller) — the
106 registry holds no active operator slot, so there is no actor
107 to attribute the operations to.
108 """
109 func = "_registry_backend"
110 # Imported here, not at module scope: the file backend is the
111 # default, and a `work_queue_manage list` against it must not drag the
112 # registry's auth, signing and checkpoint stack into the process.
113 from oc_chat.registry import Registry
114 from oc_chat.registry.backends.sqlite import SQLiteBackend
115 from oc_chat.registry.discovery import discover_registry_location
116 from oc_chat.registry.queue_backend import RegistryQueueBackend
117
118 location = discover_registry_location(registry_path=args.registry)
119 storage = SQLiteBackend(location.registry_path)
120 actor_slot = args.actor_slot or storage.active_operator_slot()
121 if actor_slot is None:
122 raise QueueBackendError("no active operator slot found in the registry")
123 _dbg("OC_CHAT.MAIN", func, f"registry backend as {actor_slot}", 2)
124 return RegistryQueueBackend(
125 Registry(storage),
126 slot=args.slot or actor_slot,
127 actor_slot=actor_slot,
128 )
129
130
131def main(argv: list[str] | None = None) -> int:
132 """Run one sub-command with oc_chat's program name and registry backend."""
133 return _moved.main(argv, prog=PROG, backend_factory=_registry_backend)
134
135
136if __name__ == "__main__":
137 sys.exit(main())
QueueBackend _registry_backend(argparse.Namespace args)