zettcode-sdk 0.3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zettcode/daemon/__init__.py +17 -0
- zettcode/daemon/__main__.py +10 -0
- zettcode/daemon/cli.py +693 -0
- zettcode/daemon/companions.py +63 -0
- zettcode/daemon/process.py +559 -0
- zettcode/daemon/run.py +678 -0
- zettcode/daemon/state.py +356 -0
- zettcode/doctor.py +167 -0
- zettcode/mentions.py +320 -0
- zettcode/sdk/__init__.py +195 -0
- zettcode/sdk/builtins.py +608 -0
- zettcode/sdk/client.py +1810 -0
- zettcode/sdk/commands.py +9 -0
- zettcode/sdk/daemons.py +244 -0
- zettcode/sdk/errors.py +132 -0
- zettcode/sdk/events.py +434 -0
- zettcode/sdk/extensions/__init__.py +6 -0
- zettcode/sdk/extensions/mcp.py +276 -0
- zettcode/sdk/extensions/messaging.py +281 -0
- zettcode/sdk/handlers.py +126 -0
- zettcode/sdk/messenger.py +299 -0
- zettcode/sdk/models.py +156 -0
- zettcode/sdk/py.typed +0 -0
- zettcode/sdk/session.py +1212 -0
- zettcode/sdk/translation.py +384 -0
- zettcode/sdk/types.py +907 -0
- zettcode/table.py +95 -0
- zettcode_sdk-0.3.4.dist-info/METADATA +21 -0
- zettcode_sdk-0.3.4.dist-info/RECORD +30 -0
- zettcode_sdk-0.3.4.dist-info/WHEEL +4 -0
zettcode/table.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Plain-text layout for the command line: columns measured in terminal cells, not in characters.
|
|
2
|
+
|
|
3
|
+
A command that prints a table has two ways to get it wrong. ``len`` counts a Chinese character as one cell when a
|
|
4
|
+
terminal gives it two, so a column of mixed names is crooked; and one row of many columns is wider than the terminal
|
|
5
|
+
it is printed to. :func:`table` measures with :func:`display_width`, and :func:`block` lays one field per line, which
|
|
6
|
+
is what a record with ten fields needs. Both are stdlib only, so any command may import them.
|
|
7
|
+
|
|
8
|
+
A cell's text is shown, not interpreted: a newline, a tab, an escape or a bidi override in a title becomes a space,
|
|
9
|
+
so a value can never break the layout or turn the rest of the line around; :func:`pad` does the same. Width is counted
|
|
10
|
+
per code point, with combining marks, joiners, variation selectors and skin-tone modifiers taking none; a joined emoji
|
|
11
|
+
is measured as its parts, which is wider than the one glyph a terminal may draw, and that is the limit of what this
|
|
12
|
+
can know without a terminal.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import unicodedata
|
|
18
|
+
from collections.abc import Iterable, Sequence
|
|
19
|
+
|
|
20
|
+
__all__ = ["block", "display_width", "pad", "table"]
|
|
21
|
+
|
|
22
|
+
#: Categories a character keeps to itself: an accent on the letter before it, a joining mark, a direction mark.
|
|
23
|
+
_ZERO_WIDTH = ("Mn", "Me", "Cf")
|
|
24
|
+
|
|
25
|
+
#: Format characters that reorder or hide what follows: a right-to-left override turns the rest of the line around.
|
|
26
|
+
_BIDI = frozenset("\u061c\u200e\u200f\u202a\u202b\u202c\u202d\u202e\u2066\u2067\u2068\u2069")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def display_width(text: str) -> int:
|
|
30
|
+
"""Return how many terminal cells ``text`` takes.
|
|
31
|
+
|
|
32
|
+
An East Asian wide or fullwidth character takes two cells; a combining mark, a joiner, a variation selector, a
|
|
33
|
+
skin-tone modifier or another format character (``Cf``) takes none; everything else takes one.
|
|
34
|
+
"""
|
|
35
|
+
cells = 0
|
|
36
|
+
for character in text:
|
|
37
|
+
if unicodedata.category(character) in _ZERO_WIDTH or _modifier(character):
|
|
38
|
+
continue
|
|
39
|
+
cells += 2 if unicodedata.east_asian_width(character) in ("W", "F") else 1
|
|
40
|
+
return cells
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _modifier(character: str) -> bool:
|
|
44
|
+
"""Return whether ``character`` only changes the glyph before it: a variation selector or a skin tone."""
|
|
45
|
+
return "\ufe0e" <= character <= "\ufe0f" or "\U0001f3fb" <= character <= "\U0001f3ff"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _shown(text: str) -> str:
|
|
49
|
+
"""Return ``text`` with the characters a terminal would act on rather than show replaced by spaces."""
|
|
50
|
+
return "".join(
|
|
51
|
+
" " if unicodedata.category(character) in ("Cc", "Cs", "Zl", "Zp") or character in _BIDI else character
|
|
52
|
+
for character in text
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def pad(text: str, width: int) -> str:
|
|
57
|
+
"""Return ``text`` followed by the spaces that make it ``width`` cells wide; a wider one is left alone.
|
|
58
|
+
|
|
59
|
+
Control characters are shown as spaces here too, so a caller that pads with this cannot break its own line.
|
|
60
|
+
"""
|
|
61
|
+
shown = _shown(text)
|
|
62
|
+
return shown + " " * max(0, width - display_width(shown))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def table(rows: Sequence[Sequence[str]], *, indent: str = "", separator: str = " ") -> list[str]:
|
|
66
|
+
"""Return ``rows`` as aligned lines, the first row being the headings.
|
|
67
|
+
|
|
68
|
+
Each column is as wide as its widest cell in terminal cells, so a name in Chinese lines up with one in Latin.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
ValueError: A row holds a different number of cells from the first, so there is no column to put it in.
|
|
72
|
+
"""
|
|
73
|
+
if not rows:
|
|
74
|
+
return []
|
|
75
|
+
width = len(rows[0])
|
|
76
|
+
if any(len(row) != width for row in rows):
|
|
77
|
+
raise ValueError(f"every row of a table needs {width} cells")
|
|
78
|
+
shown = [[_shown(cell) for cell in row] for row in rows]
|
|
79
|
+
widths = [max(display_width(row[index]) for row in shown) for index in range(width)]
|
|
80
|
+
return [
|
|
81
|
+
(indent + separator.join(pad(cell, widths[index]) for index, cell in enumerate(row))).rstrip() for row in shown
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def block(fields: Iterable[tuple[str, str]], *, indent: str = " ", separator: str = " ") -> list[str]:
|
|
86
|
+
"""Return one line per ``(label, value)``, the labels padded to the widest of them.
|
|
87
|
+
|
|
88
|
+
This is the layout for a record: a table with one row per field and no heading, so a value may hold a path, a
|
|
89
|
+
sentence or a title without widening every other row.
|
|
90
|
+
"""
|
|
91
|
+
pairs = [(_shown(label), _shown(value)) for label, value in fields]
|
|
92
|
+
if not pairs:
|
|
93
|
+
return []
|
|
94
|
+
width = max(display_width(label) for label, _ in pairs)
|
|
95
|
+
return [f"{indent}{pad(label, width)}{separator}{value}".rstrip() for label, value in pairs]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: zettcode-sdk
|
|
3
|
+
Version: 0.3.4
|
|
4
|
+
Summary: The documented, stable Python surface over ZettCode: sessions, runs, models, daemons
|
|
5
|
+
Project-URL: Repository, https://github.com/Chang-LeHung/zettcode
|
|
6
|
+
Author: Chang-LeHung
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: agent,sdk,zettcode
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: httpx<1,>=0.27
|
|
19
|
+
Requires-Dist: zett-agent<0.3,>=0.2.7
|
|
20
|
+
Requires-Dist: zettcode-broker
|
|
21
|
+
Requires-Dist: zettcode-engine
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
zettcode/doctor.py,sha256=7wNHm_or83TSL3cV1YjoJUWXb-syTPGLirL0ueb9PTw,6976
|
|
2
|
+
zettcode/mentions.py,sha256=ObKgfoNsVF26atYlZXyBBuLkE_oewtatrxduLQyRaPQ,13730
|
|
3
|
+
zettcode/table.py,sha256=VL1miiuBkq7sk8Rr2G_aOpV1IsJjlg62QwoAkrrXDCY,4557
|
|
4
|
+
zettcode/daemon/__init__.py,sha256=bepYUKyEnsis1e-JJwSw6slnXs3AsqTiz7g1iaSHcyo,943
|
|
5
|
+
zettcode/daemon/__main__.py,sha256=jaKXXQMUGDPC0rmJ2_e3E7s_u7xfW4yT9B5y_r-cV7k,263
|
|
6
|
+
zettcode/daemon/cli.py,sha256=xGcp5RH33kVBLoGMW9LsyEZP_TQmvpYzn42n3WA9MtA,28124
|
|
7
|
+
zettcode/daemon/companions.py,sha256=udz_cd_A4oqxl9BbqBq5JeZz19e9Kb3DhpgGPYB94_0,2763
|
|
8
|
+
zettcode/daemon/process.py,sha256=y4fmOZ7y6cOvEJenE5uzTn7HNJlOLLAYG3gPGZlYbRU,25571
|
|
9
|
+
zettcode/daemon/run.py,sha256=UdW_dwYSRzwB9gAzKqhBHuFP6nmrrYnXgAjghtT6aNk,33800
|
|
10
|
+
zettcode/daemon/state.py,sha256=abgM5NLQMTQRpVbooY8hh0vK_CNN7wvNF-6NP8rS-IE,15974
|
|
11
|
+
zettcode/sdk/__init__.py,sha256=PZiUsPvm1tkYNh9ycVe3t7zZHM3NhV4D8d7OWv5CNmY,6465
|
|
12
|
+
zettcode/sdk/builtins.py,sha256=SzsjBptA8Wiqog6vxC9vt3D7BN9hKzHsfbDqZrZi3W8,25121
|
|
13
|
+
zettcode/sdk/client.py,sha256=ammzc0Knl2GVx3TjYVTJS0c2OoHQTmfS3PWh0DkY0uw,78639
|
|
14
|
+
zettcode/sdk/commands.py,sha256=6iHuJDPxh0Uc1AlrYyRZEr681ZKdXVcIs355xmSZedA,494
|
|
15
|
+
zettcode/sdk/daemons.py,sha256=pT8s6T7RoyNaVqaAtFPyA1gt1HqkbBKS5AO3zuckdFc,10468
|
|
16
|
+
zettcode/sdk/errors.py,sha256=gFCjSwEohoxiI2WE4WL7edbCXMRn93tGPociRLAv9vU,4939
|
|
17
|
+
zettcode/sdk/events.py,sha256=2pavVQvwM_UuiXV6YUmJy7fuRO0ta9tL8sDer0MZ06M,14051
|
|
18
|
+
zettcode/sdk/handlers.py,sha256=NeU2ZA_G38kk0rPhQJKzSD3BgaJ4ix9-EVsskZM9wRI,5439
|
|
19
|
+
zettcode/sdk/messenger.py,sha256=FqHjN4Pzuh2bD_4fef0_eJMynyVF2AZH7TZZPKpbWbg,13416
|
|
20
|
+
zettcode/sdk/models.py,sha256=4qtlp3hpGEut5ncqWkD9qMkEwF7Ka3LU9Hjumc1cXaU,6900
|
|
21
|
+
zettcode/sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
zettcode/sdk/session.py,sha256=USdy5zbtFdtkUyYCoNO-wX0kxsRaNypMSyv8mVHL-oQ,51394
|
|
23
|
+
zettcode/sdk/translation.py,sha256=HFZYHrNoUu70Uzdi0V9hAp9Zou5MNKAN8hz1zOUFmMw,16063
|
|
24
|
+
zettcode/sdk/types.py,sha256=TPc7JM8D0g8WZdk0Zt3aGjZGp7TsBqqZtyzwBjW_ioM,33904
|
|
25
|
+
zettcode/sdk/extensions/__init__.py,sha256=mwyP4MwOCD6dRAY57YHVXFGCZXL4xhB0c_FCX__DFQc,433
|
|
26
|
+
zettcode/sdk/extensions/mcp.py,sha256=CtLlhJ439W5k7JlhKrrpicYijdDTCuuo0-_JUIy7y6E,14171
|
|
27
|
+
zettcode/sdk/extensions/messaging.py,sha256=lsvb55CuyH7ZH1YOIeGkisxgjZTxWd7hvd0tAWuiDOY,16216
|
|
28
|
+
zettcode_sdk-0.3.4.dist-info/METADATA,sha256=2LGzTgLlRnhBt0ZhHomHEt90MHgnkNBgs301Hji44Ng,834
|
|
29
|
+
zettcode_sdk-0.3.4.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
30
|
+
zettcode_sdk-0.3.4.dist-info/RECORD,,
|