Files
tai/taicpp/tests/misc_py.py
T

1168 lines
58 KiB
Python

#!/usr/bin/env python3
"""Python reference driver for the differential tests of the misc modules (tests/misc_diff.py).
Runs one scenario against the real tai.py and prints a line-oriented transcript. The C++ side
(tests/misc_driver.cpp) prints the same transcript for the same scenario; the orchestrator diffs them.
Usage: misc_py.py SCENARIO ROOT [prepare]
"""
import importlib.util
import json
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
TAI_PY = os.path.join(os.path.dirname(os.path.dirname(HERE)), "tai.py")
DATA = os.path.join(HERE, "misc_data")
def load_tai():
spec = importlib.util.spec_from_file_location("tai", TAI_PY)
mod = importlib.util.module_from_spec(spec)
sys.modules["tai"] = mod
spec.loader.exec_module(mod)
return mod
tai = load_tai()
def data(name):
with open(os.path.join(DATA, name), encoding="utf-8") as handle:
return json.load(handle)
def j(value):
return json.dumps(value)
def out(line=""):
sys.stdout.write(line + "\n")
def show(label, text):
out("%s: %s" % (label, j(text)))
# ------------------------------------------------------------------ scenarios without state
def sc_json(root):
for case in data("json_cases.json"):
try:
value = json.loads(case)
out("%s => %s" % (j(case), json.dumps(value)))
except ValueError:
out("%s => ERR" % j(case))
def sc_datetime(root):
for case in data("datetime_cases.json"):
try:
moment = tai._fromisoformat(case)
iso = moment.isoformat()
except Exception:
iso = "ERR"
try:
parsed = tai.parse_schedule_at(case)
except Exception as exc:
parsed = "ERR " + str(exc)
shown = "-"
if not parsed.startswith("ERR"):
try:
shown = j(tai.local_display(parsed))
except Exception as exc:
shown = "ERR " + str(exc)
out("%s => %s | %s | %s" % (j(case), iso, parsed, shown))
for case in data("duration_cases.json"):
out("duration %s => %s" % (j(case), j(tai.parse_duration(case))))
for case in data("delay_cases.json"):
out("delay %s => %s" % (j(case), j(tai.format_delay(case))))
def sc_chunk(root):
for case in data("chunk_cases.json"):
chunks = tai.chunk_lines(case["text"], case["max_lines"], case["overlap"], case["max_chars"])
out("chunks %d %s" % (len(chunks), j(chunks)))
out("collapse %s" % j(tai.collapse_repeated_lines(case["text"])))
out("lines %s" % j(case["text"].splitlines()))
out("strip %s" % j(case["text"].strip()))
def sc_fts(root):
for case in data("fts_cases.json"):
terms = tai.fts_escape(case)
out("%s => %s" % (j(case), j(terms)))
if terms:
out(" match %s" % j(tai.fts_match(terms)))
out(" or %s" % j(tai.fts_match_or(terms)))
out(" prefix %s" % j(tai.fts_match_prefix(terms)))
out(" variants %s" % j(tai.fts_match_variants(terms)))
out("rank %s" % j(tai.fts_rank("fts_docs")))
for raw in ["Release Notes!", " a b ", "---", "x" * 40, "été", "a,b;c", "Hello World 2", "..", "UPPER", "a-b-c"]:
out("tag %s => %s" % (j(raw), j(tai.normalize_tag(raw))))
out("tags %s" % j(tai.normalize_tags(["A b", "a-b", "", "C!", "d" * 40, "d" * 39 + "e"] + ["t%d" % i for i in range(30)])))
def sc_skills_data(root):
for name in sorted(tai.BUNDLED_SKILLS):
out("skill %s upstream %s" % (name, j(tai.BUNDLED_SKILL_UPSTREAM[name])))
for rel in sorted(tai.BUNDLED_SKILLS[name]):
text = tai.BUNDLED_SKILLS[name][rel]
out(" file %s len %d sha8 %s sha256 %s" % (rel, len(text.encode("utf-8")), tai.bundled_skill_digest(text), __import__("hashlib").sha256(text.encode("utf-8")).hexdigest()))
for name in sorted(tai.SKILL_BLUEPRINTS):
bp = tai.SKILL_BLUEPRINTS[name]
out("blueprint %s hint %s scope %s brief %s" % (name, j(bp["hint"]), bp["scope"], j(bp["brief"])))
out("catalog empty %s" % j(tai.skill_catalog({})))
out("catalog one %s" % j(tai.skill_catalog({"deep-research": {"description": "x" * 400}, "zeta": {"description": "short"}})))
out("prompt %s" % j(tai.create_skill_prompt("my-skill", "do the thing", "/tmp/x/my-skill")))
for raw in ["a", "ab", "a-b", "-a", "a-", "A", "a_b", "a" * 64, "a" * 65, "", "a b", "0x", "a\n"]:
out("name %s => %s" % (j(raw), bool(tai.SKILL_NAME_RE.match(raw))))
front_cases = [
["name: x", "description: y"],
["name: 'x'", 'description: "y z"'],
["name: x", "description: >", " line one", " line two", "other: v"],
["name: x", "description: |", " line one", " line two", "tail: 1"],
["name: x", "description: >-", " folded"],
[" indented: no", "key: va:lue", "noval", "k2:", "k3: ''quoted''"],
["a: >", "b: 1"],
["a: |", "\tt1", " t2", "z: 9"],
]
for lines in front_cases:
out("front %s => %s" % (j(lines), j(tai.parse_skill_front(lines))))
# ------------------------------------------------------------------ helpers for filesystem scenarios
def write(path, text):
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w", encoding="utf-8", newline="") as handle:
handle.write(text)
def read(path):
with open(path, encoding="utf-8", newline="") as handle:
return handle.read()
def tai_home():
return os.environ["TAI_HOME"]
def sc_skills_files(root):
home = tai_home()
out("== front-matter parse")
cases = {
"ok": "---\nname: ok\ndescription: fine one\n---\n\n\nbody here\n",
"crlf": "---\r\nname: crlf\r\ndescription: win\r\n---\r\nbody\r\n",
"nofront": "just text\n",
"noend": "---\nname: noend\ndescription: d\n",
"badname": "---\nname: Bad_Name\ndescription: d\n---\nbody\n",
"nodesc": "---\nname: nodesc\n---\nbody\n",
"quoted": "---\nname: 'quoted'\ndescription: \"has: colon\"\n---\nbody\n",
"folded": "---\nname: folded\ndescription: >\n one\n two\n---\nbody\n",
"emptybody": "---\nname: emptybody\ndescription: d\n---",
}
for key, text in cases.items():
path = os.path.join(root, "parse", key, "SKILL.md")
write(path, text)
skill = tai.parse_skill_file(path)
out("parse %s => %s" % (key, j(skill)))
out("== discover with external roots and collisions")
proj = os.path.join(root, "proj")
write(os.path.join(os.path.expanduser("~"), ".claude", "skills", "ext-home", "SKILL.md"), "---\nname: ext-home\ndescription: from claude home\n---\nbody ext-home\n")
write(os.path.join(os.path.expanduser("~"), ".claude", "skills", "shared", "SKILL.md"), "---\nname: shared\ndescription: external copy\n---\nbody external\n")
write(os.path.join(proj, ".claude", "skills", "proj-claude", "SKILL.md"), "---\nname: proj-claude\ndescription: project claude\n---\nbody pc\n")
write(os.path.join(proj, ".agents", "skills", "proj-agents", "SKILL.md"), "---\nname: proj-agents\ndescription: project agents\n---\nbody pa\n")
write(os.path.join(home, "skills", "shared", "SKILL.md"), "---\nname: shared\ndescription: tai copy\n---\nbody tai\n")
write(os.path.join(home, "skills", "native", "SKILL.md"), "---\nname: native\ndescription: native home skill\n---\nbody native\n")
write(os.path.join(home, "skills", "native", "scripts", "run.sh"), "echo hi\n")
write(os.path.join(home, "skills", "native", "references", "ref.md"), "ref\n")
write(os.path.join(home, "skills", "native", "assets", "a.txt"), "a\n")
write(os.path.join(proj, ".tai", "skills", "proj-tai", "SKILL.md"), "---\nname: proj-tai\ndescription: project tai skill\n---\nbody ptai\n")
write(os.path.join(home, "skills", "broken", "SKILL.md"), "no front matter\n")
write(os.path.join(home, "skills", "stray-file.txt"), "x\n")
tai.save_skill_install_meta(os.path.join(home, "skills"), "native", {"source": "/some/path", "mode": "symlink", "scope": "home", "n": 3, "nested": {"a": [1, None, True]}})
skills = tai.discover_skills(home, proj)
for name in skills:
s = skills[name]
out("skill %s root=%s managed=%s install=%s note=%s extras=%s" % (name, s["root"], s["managed"], j(s["install"]), j(tai.skill_provenance_note(s)), j(tai.skill_extra_files(s["root"]))))
out(" desc=%s body=%s" % (j(s["description"]), j(s["body"])))
out("order %s" % j(list(skills)))
out("catalog %s" % j(tai.skill_catalog(skills)))
out("== scope helpers")
for scope in ("project", "home"):
out("scope_dir %s %s" % (scope, tai.skill_scope_dir(scope, home, proj, "nm")))
out("scope_dir %s %s" % (scope, tai.skill_scope_dir(scope, home, proj)))
empty = os.path.join(root, "emptyproj")
os.makedirs(empty, exist_ok=True)
out("default scope empty %s" % tai.default_skill_scope(empty))
for marker in (".git", ".tai", ".claude/skills", ".agents/skills"):
d = os.path.join(root, "mk-" + marker.replace("/", "_"))
os.makedirs(os.path.join(d, marker), exist_ok=True)
out("default scope %s %s" % (marker, tai.default_skill_scope(d)))
for path in ("/a/b/.claude/skills/x", "/a/b/.agents/skills/x/", "/a/b/other/x", "/a/.claude/skills/../x", "/a/.claude/skills//x"):
out("external %s %s" % (path, tai.is_external_skill_root(path)))
out("meta none %s" % j(tai.load_skill_install_meta(os.path.join(home, "skills"), "nothing")))
write(os.path.join(home, "skills", ".installs", "bad.json"), "{not json")
out("meta bad %s" % j(tai.load_skill_install_meta(os.path.join(home, "skills"), "bad")))
out("meta ok %s" % j(tai.load_skill_install_meta(os.path.join(home, "skills"), "native")))
def sc_skills_ops(root):
home = tai_home()
def tree():
found = []
base = os.path.join(home, "skills")
for dirpath, _dirs, files in os.walk(base):
for f in files:
found.append(os.path.relpath(os.path.join(dirpath, f), base))
return sorted(found)
def step(label, mode):
out("%s => %s" % (label, tai.op_skills(mode, home)))
out(" status: %s" % tai.status_lines(home)[-2])
out(" files: %d" % len(tree()))
out("-- fresh")
step("install", "install")
step("install again", "install")
step("upgrade clean", "upgrade")
out("pristine all %s" % j([tai.bundled_skill_pristine(home, n) for n in sorted(tai.BUNDLED_SKILLS)]))
taste = os.path.join(home, "skills", "taste", "SKILL.md")
write(taste, "user rewrite")
out("-- modified taste")
step("install", "install")
step("upgrade", "upgrade")
extra = os.path.join(home, "skills", "taste", "mynotes.md")
write(extra, "mine")
step("reinstall", "reinstall")
out("extra kept %s" % os.path.isfile(extra))
out("-- crlf edit counts as equal after universal newlines")
path = os.path.join(home, "skills", "plan", "SKILL.md")
write(path, read(path).replace("\n", "\r\n"))
step("upgrade crlf", "upgrade")
out("-- uninstall with user content")
gitp = os.path.join(home, "skills", "git", "SKILL.md")
write(gitp, "user rewrite git")
gextra = os.path.join(home, "skills", "git", "mynotes.md")
write(gextra, "mine")
write(os.path.join(home, "skills", "git", "sub", "deep.txt"), "deep")
step("uninstall", "uninstall")
step("uninstall again", "uninstall")
os.remove(gitp)
os.remove(gextra)
os.remove(os.path.join(home, "skills", "git", "sub", "deep.txt"))
step("uninstall final", "uninstall")
step("uninstall empty", "uninstall")
out("-- sidecar-only uninstall")
tai.save_skill_install_meta(os.path.join(home, "skills"), "taste", {"files": {}})
step("uninstall sidecar", "uninstall")
out("-- tracked-digest removal of an edited file")
step("install", "install")
meta = tai.load_skill_install_meta(os.path.join(home, "skills"), "taste")
out("meta %s" % j(sorted(meta)))
out("meta files %s" % j(meta["files"]))
out("meta fixed %s" % j({k: meta[k] for k in ("source", "mode", "scope", "upstream", "bundled_version")}))
os.chmod(os.path.join(home, "skills", "taste"), 0o500)
step("install readonly", "install")
os.chmod(os.path.join(home, "skills", "taste"), 0o700)
out("-- error path: skills dir is a file")
other = os.path.join(root, "home2")
os.makedirs(other, exist_ok=True)
write(os.path.join(other, "skills"), "file not dir")
out("blocked => %s" % tai.op_skills("install", other))
out("blocked uninstall => %s" % tai.op_skills("uninstall", other))
sc_skills_install_tool(root)
class SkillApp:
def __init__(self, home, cwd):
self.config = type("C", (), {"home": home})()
self.profile = "default"
self.skills = {}
self.store = None
self.depth = 0
self.runner_override = None
self.approvals = []
self.refreshed = 0
self.approve = True
def ask_approval(self, text):
self.approvals.append(text)
return self.approve
def apply_system(self):
self.refreshed += 1
def sc_skills_install_tool(root):
home = tai_home()
proj = os.path.join(root, "proj")
os.chdir(proj)
app = SkillApp(home, proj)
app.skills = tai.discover_skills(home, proj)
tools = tai.Tools(app)
out("== install_skill / load_skill / create_skill")
src = os.path.join(root, "srcskill")
write(os.path.join(src, "SKILL.md"), "---\nname: from-src\ndescription: installed from a dir\n---\nbody src\n")
write(os.path.join(src, "scripts", "x.sh"), "echo x\n")
write(os.path.join(src, "references", "r.md"), "r\n")
nested = os.path.join(root, "nested")
write(os.path.join(nested, "inner", "SKILL.md"), "---\nname: inner\ndescription: nested one\n---\nbody inner\n")
two = os.path.join(root, "two")
write(os.path.join(two, "a", "SKILL.md"), "---\nname: aa\ndescription: d\n---\nb\n")
write(os.path.join(two, "b", "SKILL.md"), "---\nname: bb\ndescription: d\n---\nb\n")
barefile = os.path.join(root, "bare.md")
write(barefile, "---\nname: bare-one\ndescription: bare md file\n---\nbody bare\n")
badfile = os.path.join(root, "bad.md")
write(badfile, "no front\n")
ext = os.path.join(proj, ".claude", "skills", "extskill")
write(os.path.join(ext, "SKILL.md"), "---\nname: extskill\ndescription: external one\n---\nbody ext\n")
notes = []
def call(label, args):
res = tools.dispatch("install_skill", json.dumps(args))
out("%s => %s" % (label, j(res)))
call("empty", {"source": ""})
call("bad scope", {"source": src, "scope": "mars"})
call("bad mode", {"source": src, "mode": "link"})
call("missing", {"source": os.path.join(root, "nope")})
call("dir home", {"source": src, "scope": "home"})
call("dir home again denied?", {"source": src, "scope": "home"})
app.approve = False
call("dir home denied", {"source": src, "scope": "home"})
app.approve = True
call("dir home force", {"source": src, "scope": "home", "force": True})
call("dir project", {"source": src, "scope": "project", "name": "renamed"})
call("bad name", {"source": src, "name": "Bad Name"})
call("nested", {"source": nested, "scope": "home"})
call("two children", {"source": two, "scope": "home"})
call("bare file", {"source": barefile, "scope": "home"})
call("bad file", {"source": badfile})
call("symlink ext default", {"source": ext, "scope": "home"})
call("symlink explicit", {"source": src, "scope": "home", "mode": "symlink", "name": "linked", "force": True})
call("symlink bare", {"source": barefile, "mode": "symlink"})
call("not a skill source", {"source": "/dev/null"})
out("approvals %s" % j(app.approvals))
out("refreshed %d" % app.refreshed)
out("skills %s" % j(sorted(app.skills)))
out("== load_skill")
app.skills = tai.discover_skills(home, proj)
for name in ("from-src", "deep-research", "extskill", "bot-creator", "nonexistent", ""):
if name == "bot-creator":
continue
out("load %s => %s" % (j(name), j(tools.dispatch("load_skill", json.dumps({"name": name})))))
out("== create_skill")
app.runner_override = lambda prompt, profile, timeout: "worker said: " + prompt[:40] + " t=%s" % timeout
for args in ({"name": "", "brief": "b"}, {"name": "ok-name", "brief": ""}, {"name": "ok-name", "brief": "b", "scope": "mars"},
{"name": "made", "brief": "make it", "scope": "home", "timeout": 10}, {"name": "made2", "brief": "make it", "timeout": "abc"},
{"name": "made3", "brief": "x", "timeout": 99999}):
out("create %s => %s" % (j(args), j(tools.dispatch("create_skill", json.dumps(args)))))
app.depth = 5
out("create depth => %s" % j(tools.dispatch("create_skill", json.dumps({"name": "dd", "brief": "b"}))))
app.depth = 0
def worker(prompt, profile, timeout):
marker = "Create a new agent skill named 'wrote' in "
path = prompt[len(marker):].split(".\n", 1)[0]
write(os.path.join(path, "SKILL.md"), "---\nname: wrote\ndescription: written by worker\n---\nbody wrote\n")
return "done writing " + path.replace(root, "<ROOT>")
app.runner_override = worker
out("create written => %s" % j(tools.dispatch("create_skill", json.dumps({"name": "wrote", "brief": "w", "scope": "home"})).replace(root, "<ROOT>")))
out("create replaced => %s" % j(tools.dispatch("create_skill", json.dumps({"name": "wrote", "brief": "w", "scope": "home"})).replace(root, "<ROOT>")))
out("refreshed %d" % app.refreshed)
# ------------------------------------------------------------------ install scenarios
class FakeBox:
"""Deterministic stand-in for the container probes (patched into tai.py; the C++ twin is FakeBox in the driver)."""
def __init__(self, engine, state, venv, ensure_error):
self.engine, self.state, self.venv, self.ensure_error = engine, state, venv, ensure_error
def install(self):
tai.container_engine = lambda: self.engine
tai.box_state = lambda engine: self.state
tai.box_venv_state = lambda engine: self.venv
def ensure():
if self.ensure_error:
raise tai.BackendError(self.ensure_error)
return self.engine
tai.ensure_box = ensure
def install_env(root, engine=None, state="running", venv="venv ready", ensure_error=""):
FakeBox(engine, state, venv, ensure_error).install()
def sc_install_hooks(root):
install_env(root)
home = tai_home()
rc = os.path.join(os.path.expanduser("~"), ".bashrc")
zrc = os.path.join(os.path.expanduser("~"), ".zshrc")
write(rc, "# my bashrc\nexport A=1")
write(zrc, "")
steps = [
("bash install", lambda: tai.op_hook("install", home)),
("bash install again", lambda: tai.op_hook("install", home)),
("bash upgrade", lambda: tai.op_hook("upgrade", home)),
("plexer install", lambda: tai.op_plexer_hook("install", home)),
("plexer again", lambda: tai.op_plexer_hook("install", home)),
("zsh install", lambda: tai.op_zsh_hook("install", home)),
("zsh again", lambda: tai.op_zsh_hook("install", home)),
("fish install", lambda: tai.op_fish_hook("install", home)),
("zsh plexer install", lambda: tai.op_zsh_plexer_hook("install", home)),
("fish plexer install", lambda: tai.op_fish_plexer_hook("install", home)),
("status", lambda: "\n".join(tai.status_lines(home))),
("bash reinstall", lambda: tai.op_hook("reinstall", home)),
("plexer reinstall", lambda: tai.op_plexer_hook("reinstall", home)),
("zsh uninstall", lambda: tai.op_zsh_hook("uninstall", home)),
("fish uninstall", lambda: tai.op_fish_hook("uninstall", home)),
("zsh uninstall again", lambda: tai.op_zsh_hook("uninstall", home)),
("bash uninstall", lambda: tai.op_hook("uninstall", home)),
("plexer uninstall", lambda: tai.op_plexer_hook("uninstall", home)),
("zsh plexer uninstall", lambda: tai.op_zsh_plexer_hook("uninstall", home)),
("fish plexer uninstall", lambda: tai.op_fish_plexer_hook("uninstall", home)),
("status after", lambda: "\n".join(tai.status_lines(home))),
]
for label, fn in steps:
out("%s => %s" % (label, j(fn())))
out("rc %s" % j(read(rc)))
out("zrc %s" % j(read(zrc)))
out("== stale and duplicated blocks")
write(rc, "head\n" + tai.BASHRC_MARK_BEGIN + "\nstale content\n" + tai.BASHRC_MARK_END + "\nmid\n" + tai.BASHRC_MARK_BEGIN + "\nsecond stale\n" + tai.BASHRC_MARK_END + "\ntail\n")
out("install over stale => %s" % j(tai.op_hook("install", home)))
out("rc %s" % j(read(rc)))
write(rc, "x\n" + tai.BASHRC_MARK_BEGIN + "\nunterminated\n")
out("install over unterminated => %s" % j(tai.op_hook("install", home)))
out("rc %s" % j(read(rc)))
out("uninstall unterminated => %s" % j(tai.op_hook("uninstall", home)))
out("rc %s" % j(read(rc)))
write(rc, "crlf\r\nline\r\n")
out("install crlf => %s" % j(tai.op_hook("install", home)))
out("rc %s" % j(read(rc)))
os.chmod(rc, 0o400)
out("readonly install => %s" % j(tai.op_plexer_hook("install", home)))
os.chmod(rc, 0o600)
blocks = [tai.hook_present, tai.zsh_hook_present, tai.fish_hook_present, tai.plexer_hook_present, tai.zsh_plexer_hook_present, tai.fish_plexer_hook_present]
out("present %s" % j([fn(rc) for fn in blocks]))
out("present missing %s" % j([fn(os.path.join(root, "nope")) for fn in blocks]))
for shell in ("bash", "zsh", "fish", "other"):
out("rc path %s %s" % (shell, tai.shell_rc_path(shell)))
os.environ["XDG_CONFIG_HOME"] = os.path.join(root, "xdg")
out("rc path fish xdg %s" % tai.shell_rc_path("fish"))
del os.environ["XDG_CONFIG_HOME"]
out("shell_present %s" % j([tai.shell_present(n) for n in ("zsh", "fish", "bash", "nosuchshell")]))
def sc_install_ops(root):
install_env(root, engine="podman", state="running", venv="venv ready")
home = tai_home()
out("-- binary")
for mode in ("install", "install", "upgrade", "reinstall", "uninstall", "uninstall", "install"):
out("binary %s => %s" % (mode, j(tai.op_binary(mode, home))))
target = os.path.join(os.path.expanduser("~"), ".local", "bin", "tai.py")
out("binary mode %s size_equal %s" % (oct(os.stat(target).st_mode & 0o777), os.path.getsize(target) == os.path.getsize(tai.__file__)))
write(target, "VERSION = \"0.0.1\"\n")
out("binary refresh => %s" % j(tai.op_binary("install", home)))
out("binary refresh upgrade => %s" % j(tai.op_binary("upgrade", home)))
out("script_version %s %s %s" % (j(tai.script_version(target)), j(tai.script_version(os.path.join(root, "nope"))), j(tai.script_version(tai.__file__))))
write(os.path.join(root, "v1"), "x\nVERSION = \"1.2.3\"\ny\n")
write(os.path.join(root, "v2"), "VERSION = \"1.2\"\n VERSION = \"1.2.3\"\nVERSION = \"a.b.c\"\n")
write(os.path.join(root, "v3"), "VERSION = \"4.5.6\"")
write(os.path.join(root, "v4"), "VERSION = \"4.5.6\" \n")
out("script_version v1..v4 %s" % j([tai.script_version(os.path.join(root, n)) for n in ("v1", "v2", "v3", "v4")]))
out("-- venv")
for mode in ("install", "install", "reinstall", "uninstall", "uninstall", "install"):
out("venv %s => %s" % (mode, j(tai.op_venv(mode, home).replace(root, "<ROOT>"))))
out("venv helpers %s %s %s" % (j(tai.venv_dir(home).replace(root, "<ROOT>")), j((tai.venv_python(home) or "").replace(root, "<ROOT>")), tai.venv_available()))
out("-- services (no systemctl)")
for mode in ("install", "install", "reinstall", "upgrade", "uninstall", "uninstall"):
out("scheduler %s => %s" % (mode, j(tai.op_scheduler_service(mode, home).replace(root, "<ROOT>"))))
out("telegram without token => %s" % j(tai.op_telegram_service("install", home)))
out("service_exec %s" % j(tai.service_exec(home, "/x/tai.py", "--a", "b").replace(root, "<ROOT>")))
out("unit_dir %s" % j(tai.unit_dir(home).replace(root, "<ROOT>")))
out("service_state %s" % j(tai.service_state("tai-scheduler.service")))
out("activate %s" % j(tai.activate_service("tai-scheduler.service")))
out("remove %s" % j(tai.remove_service_unit(home, "tai-scheduler.service")))
out("-- container")
for mode in ("install", "upgrade", "reinstall", "uninstall"):
out("container %s => %s" % (mode, j(tai.op_container(mode, home))))
install_env(root, engine="podman", state="stopped", venv="no venv (reinstall container to rebuild)")
for mode in ("install", "reinstall"):
out("container stopped %s => %s" % (mode, j(tai.op_container(mode, home))))
install_env(root, engine="podman", state="running", venv="venv ready", ensure_error="engine exploded")
out("container failing => %s" % j(tai.op_container("install", home)))
install_env(root, engine=None)
for mode in ("install", "uninstall"):
out("container noengine %s => %s" % (mode, j(tai.op_container(mode, home))))
install_env(root, engine="podman", state="running", venv="venv ready")
out("-- install_report")
for action, targets in (("install", ["skills", "bash-hook", "venv"]), ("status", ["skills"]), ("upgrade", list(tai.INSTALL_TARGETS)), ("uninstall", ["skills", "bash-hook", "plexer-hook", "binary"])):
out("report %s %s =>\n%s" % (action, targets, tai.install_report(action, targets, home).replace(root, "<ROOT>")))
out("-- install_self")
for shell in ("/bin/bash", "/usr/bin/zsh", "/usr/bin/fish", "", "/bin/sh"):
os.environ["SHELL"] = shell
out("shell %s" % j(shell))
sys.stdout.flush()
tai.install_self()
out("-- install tool")
app = SkillApp(home, root)
app.config.home = home
tools = tai.Tools(app)
for args in ({"action": "bogus"}, {"action": "status"}, {"action": "STATUS ", "targets": ["skills"]}, {"action": "install", "targets": ["nope"]}, {"action": "install", "targets": []},
{"action": "install", "targets": "skills"}, {"action": "install", "targets": ["skills"]}, {"action": "uninstall", "targets": ["skills", "bash-hook"]}, {}):
app.skills = {}
res = tools.dispatch("install", json.dumps(args)).replace(root, "<ROOT>")
out("tool %s => %s | skills=%s" % (j(args), j(res), j(sorted(app.skills))))
app.approve = False
out("tool denied => %s" % j(tools.dispatch("install", json.dumps({"action": "install", "targets": ["skills"]}))))
out("approvals %s" % j(app.approvals))
def sc_install_noengine(root):
install_env(root, engine=None)
home = tai_home()
out("%s" % j(tai.status_lines(home)[-3:]))
for mode in ("install", "uninstall"):
out("container %s => %s" % (mode, j(tai.op_container(mode, home))))
def sc_vault_line(root):
home = tai_home()
out("empty %s" % j(tai.vault_line(home)))
write(os.path.join(home, "memory.db"), "")
out("kept %s" % j(tai.vault_line(home).replace(root, "<ROOT>")))
# ------------------------------------------------------------------ scheduler scenarios
def open_store(profile="t"):
class FakeArgs:
yes = True
FakeArgs.profile = profile
config = tai.Config(FakeArgs)
seal = tai.Seal(config.home, "")
store = tai.Store(config, seal)
return config, seal, store
NOW_FIXED = "2026-10-25T12:00:00+00:00"
LONG_EVERY = 315360000 # ten years: recurring claims land far in the future so reruns are stable
def prep_sched(root):
config, seal, store = open_store()
past = "2026-01-01T00:00:00+00:00"
store.add_schedule("once-due", "do:once", "t", 0, past, 300)
store.add_schedule("rec-due", "do:rec", "t", LONG_EVERY, past, 600, ["alpha", "beta"])
store.add_schedule("future", "do:future", "t", 0, "2099-01-01T00:00:00+00:00", 600, [])
store.add_schedule("leased", "do:leased", "t", LONG_EVERY, "2026-02-01T00:00:00+00:00", 600)
store.add_schedule("stale-lease", "do:stale", "t", LONG_EVERY, "2026-03-01T00:00:00+00:00", 600)
store.add_schedule("exploder", "boom: fail", "t", 0, "2026-04-01T00:00:00+00:00", 300)
store.add_schedule("other-profile", "do:other", "other", 0, "2026-06-01T00:00:00+00:00", 300)
store.add_schedule("bad-time", "do:badtime", "t", LONG_EVERY, "!!bad", 300)
store.add_schedule("", "x" * 100, "t", 0, "2099-06-01T00:00:00+00:00", 300, ["one"])
store.add_schedule("with-result", "do:result", "t", 3600, "2099-07-01T00:00:00+00:00", 300)
store.db.execute("UPDATE schedules SET last_status = 'running', updated = ? WHERE name = 'leased'", (tai.datetime.now(tai.timezone.utc).isoformat(),))
store.db.execute("UPDATE schedules SET last_status = 'running', updated = '2000-01-01T00:00:00+00:00' WHERE name = 'stale-lease'")
store.db.execute("UPDATE schedules SET last_status = 'done', last_result = ? WHERE name = 'with-result'", ("r" * 200,))
store.db.commit()
store.close()
def sched_rows(store, label):
rows = store.db.execute("SELECT id, name, prompt, profile, every_sec, next_run, timeout, status, last_status, last_result, updated FROM schedules ORDER BY id").fetchall()
out("-- %s" % label)
for row in rows:
out("row %s" % j(list(row)))
tags = store.db.execute("SELECT item, tag, profile FROM tags WHERE item LIKE 'sched:%' ORDER BY item, tag").fetchall()
out("tags %s" % j([list(t) for t in tags]))
class Gate:
"""Blocks 'slow:' tasks until released, like a long-running worker."""
def __init__(self):
self.event = tai.threading.Event()
def runner(self, task, profile, timeout):
if task.startswith("slow:"):
self.event.wait(30)
return "slow done " + task
if "boom" in task:
raise RuntimeError("boom")
return "ok:" + task
def quiesce():
for _ in range(200):
if tai.threading.active_count() <= 1:
return
tai.time.sleep(0.05)
def sc_sched(root):
config, seal, store = open_store()
gate = Gate()
out("== list and format")
items = store.list_schedules()
for it in items:
out("item %s" % j(it))
out("format:\n%s" % tai.format_schedule_lines(items, tai._fromisoformat(NOW_FIXED)))
out("format empty: %s" % tai.format_schedule_lines([], tai._fromisoformat(NOW_FIXED)))
out("other profile: %s" % j(store.list_schedules("other")))
out("== running leases")
for status, updated, timeout in (("running", tai.datetime.now(tai.timezone.utc).isoformat(), 600), ("running", "2000-01-01T00:00:00+00:00", 600), ("done", "", 0), ("running", "garbage", 10),
("running", tai.datetime.now(tai.timezone.utc).isoformat(), 0)):
out("running %s %s %s => %s" % (status, "now" if updated.startswith("2026") else updated, timeout, tai.schedule_running(status, updated, timeout)))
out("== sealed rows (added now: Store refuses to open with them present and no passphrase)")
store.add_schedule("sealed", "tai1$AAAA$BBBB$CCCC", "t", 0, "2026-05-01T00:00:00+00:00", 300)
store.add_schedule("sealed-corrupt", "tai1$bad", "t", 0, "2026-05-02T00:00:00+00:00", 300)
out("== tick 1")
sys.stdout.flush()
fired = tai.scheduler_tick(config, seal, gate.runner)
sys.stdout.flush()
out("fired %d" % fired)
quiesce()
sched_rows(store, "after tick 1")
out("== tick 2")
out("fired %d" % tai.scheduler_tick(config, seal, gate.runner))
quiesce()
out("== cap phase")
for k in range(9):
store.add_schedule("slow%d" % k, "slow:%d" % k, "t", LONG_EVERY, "2025-01-0%dT00:00:00+00:00" % (k + 1), 600)
out("fired %d" % tai.scheduler_tick(config, seal, gate.runner))
out("fired %d" % tai.scheduler_tick(config, seal, gate.runner))
out("running agents %d" % tai.running_agents())
out("fired %d" % tai.scheduler_tick(config, seal, gate.runner))
sys.stdout.flush()
sched_rows(store, "after cap ticks")
out("== AgentsFull restore branch")
store.add_schedule("full-once", "slow:once", "t", 0, "2025-02-01T00:00:00+00:00", 600)
real = tai.running_agents
tai.running_agents = lambda: 0
out("fired %d" % tai.scheduler_tick(config, seal, gate.runner))
tai.running_agents = real
sched_rows(store, "after AgentsFull")
gate.event.set()
quiesce()
sched_rows(store, "after release")
out("== schedule tool")
app = SkillApp(tai_home(), root)
app.store = store
app.profile = "t"
tools = tai.Tools(app)
calls = [
{"prompt": ""}, {"prompt": "p"}, {"prompt": "p", "at": "2099-01-01T10:00", "every": 120}, {"prompt": "p", "at": "nonsense"}, {"prompt": "p", "every": "abc"},
{"prompt": "p", "every": 30}, {"prompt": "tool one", "at": "2099-01-01T10:00", "name": "N" * 100, "timeout": 5, "tags": ["Alpha", "beta!", "", "x" * 40]},
{"prompt": "tool two", "every": 3600, "timeout": "abc", "profile": "t"}, {"prompt": "tool three", "every": "7200", "timeout": 99999},
{"prompt": "p", "every": 60, "profile": "other"}, {"prompt": "p", "every": 60, "profile": "bad profile!"}, {"prompt": "p", "every": 60, "tags": "notalist"},
{"prompt": "p", "every": 60, "tags": [1, 2]}, {"prompt": "tool four", "every": 86400, "tags": []}, {"prompt": " padded ", "at": "2099-02-02T02:02:02Z", "timeout": 0},
{"prompt": "p", "at": "9999-12-31T24:00"}, {"prompt": "p", "at": "0001-01-01T00:00"}, {"prompt": "p", "every": 60.5}, {"prompt": "p", "every": True},
]
for args in calls:
out("schedule %s => %s" % (j(args), j(tools.dispatch("schedule", json.dumps(args)))))
app.approve = False
out("schedule denied => %s" % j(tools.dispatch("schedule", json.dumps({"prompt": "denied", "every": 60}))))
app.approve = True
out("schedules => %s" % j(tools.dispatch("schedules", "{}")))
for args in ({"id": 999}, {"id": "abc"}, {"id": 0}, {}, {"id": "13"}, {"id": 14.0}):
out("unschedule %s => %s" % (j(args), j(tools.dispatch("unschedule", json.dumps(args)))))
app.approve = False
out("unschedule denied => %s" % j(tools.dispatch("unschedule", json.dumps({"id": 15}))))
app.approve = True
out("approvals %s" % j(app.approvals))
sched_rows(store, "final")
out("remove nonexistent %s" % store.remove_schedule(99999))
store.close()
# ------------------------------------------------------------------ rag scenarios
WORDS = ("alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu "
"database retrieval indexing scheduler terminal pipeline compiler optimizer allocator tokenizer scanner buffer kernel module package release rollback deployment "
"café naïve résumé über 中文 snake_case kebab-case CamelCase ALLCAPS numbers123 v2beta").split()
def prep_rag(root):
import random
rng = random.Random(7)
config, seal, store = open_store()
ids = []
for index in range(30):
title = " ".join(rng.choice(WORDS) for _ in range(rng.randint(1, 4)))
lines = []
for _ in range(rng.randint(1, 12)):
lines.append(" ".join(rng.choice(WORDS) for _ in range(rng.randint(3, 14))))
content = "\n".join(lines)
kind = rng.choice(["note", "doc", "termlog"])
rid = store.add_record(kind, title, content, [rng.choice(["x", "y", "zed"])] if index % 3 == 0 else [], "t")
store.add_chunks("record", rid, tai.chunk_lines(content, 3, 1, 200), "t")
ids.append(rid)
store.add_record("note", "unique zebra", "the quick zebra jumps over the lazy dog " * 30, [], "t")
store.add_record("note", "other profile secret", "alpha bravo hidden", [], "other")
store.add_edge(ids[0], ids[1], "relates to", "t")
store.add_edge(ids[2], ids[0], "see also", "t")
store.add_edge(ids[0], ids[3], "x", "t")
store.add_edge(ids[0], ids[4], "y", "t")
store.add_edge(ids[0], ids[5], "z", "t")
for index in range(6):
store.audit_event("main", "write", "/tmp/file%d.txt" % index, "wrote alpha file %d" % index, None, "content %d" % index, ["t%d" % index], None, None, "t")
store.log_event("t", "user", "message", "hello alpha retrieval message")
store.log_event("t", "assistant", "message", "bravo reply about indexing")
# implicit pairs: search events followed by reads
store.log_event("t", "tool", "search-query", "q=alpha\tlimit=5\thits=record:%s,record:%s,chunk:3" % (ids[0], ids[1]))
store.log_event("t", "tool", "record-read", ids[1])
store.log_event("t", "tool", "search-query", "q=nothing here\tlimit=5\thits=")
store.log_event("t", "tool", "search-query", "q=bravo\tlimit=5\thits=%s,record:%s" % (ids[2], ids[3]))
store.log_event("t", "tool", "record-read", " %s " % ids[9])
store.log_event("t", "tool", "record-read", ids[2])
store.log_event("t", "tool", "search-query", "no equals sign")
store.log_event("t", "tool", "search-query", "q=\thits=x")
store.log_event("t", "tool", "search-query", "q=a=b\tq=delta\thits=,,record:%s," % ids[6])
store.log_event("t", "tool", "record-read", "")
store.close()
def hit_json(h):
return {"item": h["item"], "kind": h["kind"], "sub": h["sub"], "title": h["title"], "snippet": h["snippet"], "rank": h["rank"]}
def sc_rag(root):
config, seal, store = open_store()
out("== fts_search")
queries = ["alpha", "alpha bravo", "zebra", "café", "résumé naïve", "snake_case", "numbers123", "nothingmatchesthis", "", "!!!", "retrieval index", "wh", "ALPHA", "x" * 50, "unique zebra jumps", "message",
"file", "ro", "v2beta kernel"]
for q in queries:
for kinds in ((), ("record",), ("chunk",), ("audit",), ("event",), ("record", "chunk")):
for limit in (10, 3):
hits = store.fts_search(q, kinds, "t", limit)
out("search %s %s %d => %s" % (j(q), j(list(kinds)), limit, j([hit_json(h) for h in hits])))
out("other profile %s" % j([hit_json(h) for h in store.fts_search("alpha", ("record",), "other", 10)]))
out("limits %s" % j([len(store.fts_search("alpha", (), "t", n)) for n in (0, -5, 1, 100, 500)]))
out("== eval")
out("tokens %s" % j(tai.RetrievalEval.tokens("The quick Brown fox jumped_over 123456 abcdefg ABCDEFG cafés résumés")))
out("tokens4 %s" % j(tai.RetrievalEval.tokens("The quick Brown fox", 4)))
goldens = tai.RetrievalEval.goldens_from_vault(store, "t")
out("goldens %d" % len(goldens))
for g in goldens:
out("golden %s" % j(g))
result = tai.RetrievalEval.score(store, goldens, "t")
out("score %s" % j(result))
pairs = tai.RetrievalEval.implicit_pairs(store, "t")
out("pairs %s" % j(pairs))
out("report:\n%s" % tai.RetrievalEval.format_report(result, pairs))
out("empty report:\n%s" % tai.RetrievalEval.format_report(tai.RetrievalEval.score(store, [], "t"), tai.RetrievalEval.implicit_pairs(store, "nobody")))
out("small k %s" % j(tai.RetrievalEval.score(store, goldens[:12], "t", ("record",), 1, 2)))
out("rank_of %s %s %s" % (j(tai.RetrievalEval.rank_of("b", ["a", "b"])), j(tai.RetrievalEval.rank_of("z", ["a"])), j(tai.RetrievalEval.best_rank(["z", "a"], ["q", "a", "z"]))))
out("metrics %s" % j([tai.RetrievalEval.hit_at_k(3), tai.RetrievalEval.hit_at_k(6), tai.RetrievalEval.hit_at_k(None), tai.RetrievalEval.reciprocal_rank(4), tai.RetrievalEval.ndcg_at_k(3), tai.RetrievalEval.ndcg_at_k(9),
tai.RetrievalEval.context_precision(["a", "c"], ["a", "b", "c", "d"]), tai.RetrievalEval.context_precision([], ["a"]), tai.RetrievalEval.context_precision(["x"], ["a"])]))
for text in ("q=alpha\thits=record:m1,m2,,chunk:4", "nothing", "q=\thits=a", "a=b=c\tq= spaced \thits= x ,y ", "q=a\tq=b\thits=record:z"):
out("parse %s => %s" % (j(text), j(tai.RetrievalEval._parse_search_event(text))))
out("== chunks table")
rid = store.db.execute("SELECT id FROM records WHERE profile = 't' ORDER BY id LIMIT 1").fetchone()[0]
store.add_chunks("record", rid, ["one", "two", "three"], "t")
rows = store.db.execute("SELECT id, parent_kind, parent_id, idx, text, profile FROM chunks WHERE parent_id = ? ORDER BY idx", (rid,)).fetchall()
out("chunks %s" % j([list(r) for r in rows]))
ids = [r[0] for r in rows]
got = store.get_chunks_by_ids(ids + [999999], "t")
out("by ids %s" % j({str(k): v for k, v in sorted(got.items())}))
out("by ids empty %s other %s" % (j(store.get_chunks_by_ids([], "t")), j(store.get_chunks_by_ids(ids, "other"))))
store.add_chunks("record", rid, [], "t")
out("after clear %d" % store.db.execute("SELECT COUNT(*) FROM chunks WHERE parent_id = ?", (rid,)).fetchone()[0])
out("== search tool")
app = SkillApp(tai_home(), root)
app.store = store
app.profile = "t"
tools = tai.Tools(app)
calls = [{"query": ""}, {"query": "alpha"}, {"query": "alpha", "limit": 3}, {"query": "alpha", "limit": "2"}, {"query": "alpha", "limit": "x"}, {"query": "alpha", "limit": 0}, {"query": "alpha", "limit": -2},
{"query": "retrieval", "kinds": ["chunk"]}, {"query": "alpha", "kinds": ["record"], "expand": True, "limit": 20}, {"query": "alpha", "kinds": ["bogus"]}, {"query": "alpha", "kinds": []},
{"query": "alpha", "kinds": "record"}, {"query": "file", "kinds": ["audit"]}, {"query": "message", "kinds": ["event"]}, {"query": "zebra", "kinds": ["record", "chunk", "audit"]},
{"query": "nothingmatchesthis"}, {"query": "x" * 200}, {"query": " spaced "}, {"query": "café résumé", "limit": 50}]
for args in calls:
out("search %s => %s" % (j(args), j(tools.dispatch("search", json.dumps(args)))))
out("logged %s" % j([list(r) for r in store.db.execute("SELECT profile, role, kind, text FROM events WHERE kind = 'search-query' ORDER BY id DESC LIMIT 25").fetchall()]))
store.close()
# ------------------------------------------------------------------ telegram scenarios
class CtxDict(dict):
def __setitem__(self, key, value):
out("CTX set %s=%s" % (key, value))
dict.__setitem__(self, key, value)
def pop(self, key, *default):
out("CTX pop %s" % key)
return dict.pop(self, key, *default)
class LogStub:
enabled = False
def __init__(self):
self.context = CtxDict()
def event(self, level, component, event, message, profile="", bot="", chat="", meta=None):
out("LOG %s" % j([level, component, event, message, profile, bot, chat, meta]))
class TgAgent:
profile = "t"
bot = "main"
def __init__(self, home):
self.config = type("C", (), {"home": home})()
self.store = type("S", (), {"seal": None})()
def reset_history(self):
out("AGENT reset_history")
def run_turn(self, text, capture=False):
out("AGENT run_turn %s capture=%s" % (j(text), capture))
if "explode" in text:
raise RuntimeError("agent exploded")
if text == "long":
return "L" * 9000
if text == "empty reply":
return ""
return "echo:" + text
class StopLoop(Exception):
pass
def tg_setup(root):
tai.TELEGRAM_API = os.environ["MISC_TG_API"]
tai.TELEGRAM_FILE_API = os.environ["MISC_TG_FILE"]
tai.LOG = LogStub()
def ensure():
out("BOX ensure_box")
if os.environ.get("MISC_BOX_FAIL"):
raise tai.BackendError("box down")
return "eng"
def transcribe(engine, audio):
out("BOX transcribe %s %s" % (engine, j(audio.decode("latin-1"))))
if audio == b"AUDIO":
return "voice says hi"
return "error: model failed"
tai.ensure_box = ensure
tai.box_transcribe = transcribe
tai.start_scheduler = lambda config, seal: out("start_scheduler called")
def sc_telegram(root):
tg_setup(root)
home = tai_home()
out("== token")
env_path = tai.telegram_env_path(home)
out("env path %s" % j(env_path.replace(root, "<ROOT>")))
os.environ.pop("TELEGRAM_BOT_TOKEN", None)
out("no file => %s" % j(tai.load_telegram_token(home)))
for label, body in (("plain", "TELEGRAM_BOT_TOKEN=abc123\n"), ("quoted", "TELEGRAM_BOT_TOKEN='abc'\n"), ("dquoted", 'TELEGRAM_BOT_TOKEN="x y"\n'), ("spaces", "TELEGRAM_BOT_TOKEN= spaced \n"),
("other first", "OTHER=1\nTELEGRAM_BOT_TOKEN=second\nTELEGRAM_BOT_TOKEN=third\n"), ("none", "OTHER=1\n"), ("empty", ""), ("crlf", "TELEGRAM_BOT_TOKEN=win\r\n"),
("noeq", "TELEGRAM_BOT_TOKEN\n"), ("eq in value", "TELEGRAM_BOT_TOKEN=a=b=c\n"), ("quotes only", "TELEGRAM_BOT_TOKEN=''\n"), ("indented", " TELEGRAM_BOT_TOKEN=nope\n")):
write(env_path, body)
out("file %s => %s" % (label, j(tai.load_telegram_token(home))))
os.environ["TELEGRAM_BOT_TOKEN"] = "fromenv"
out("env wins => %s" % j(tai.load_telegram_token(home)))
os.environ["TELEGRAM_BOT_TOKEN"] = ""
out("empty env falls back => %s" % j(tai.load_telegram_token(home)))
os.environ.pop("TELEGRAM_BOT_TOKEN", None)
os.remove(env_path)
out("== call / send")
good = tai.Telegram("good")
out("getMe %s" % j(good.call("getMe", {})))
for label, token, method in (("bad token", "bad", "getMe"), ("not json", "nojson", "getMe")):
try:
res = tai.Telegram(token).call(method, {})
out("%s => %s" % (label, j(res)))
except (OSError, ValueError) as exc:
out("%s => raised %s" % (label, j(tai.short_error(exc))))
for text in ("", "short", "S" * 4000, "S" * 4001, "S" * 8000, "S" * 8001, "é" * 4001, "\U0001f600" * 4100, "line\n" * 2000):
tai.telegram_send(good, 42, text)
tai.telegram_send(good, "chat-as-string", "hi")
out("== updates")
agent = TgAgent(home)
updates = [
{"update_id": 1, "message": {"chat": {"id": 111}, "text": "/start"}},
{"update_id": 2, "message": {"chat": {"id": 111}, "text": "/new"}},
{"update_id": 3, "message": {"chat": {"id": 111}, "text": "hello there"}},
{"update_id": 4, "message": {"chat": {"id": 111}, "text": ""}},
{"update_id": 5, "message": {"chat": {"id": 111}, "text": " "}},
{"update_id": 6, "message": {"chat": {"id": 0}, "text": "zero chat"}},
{"update_id": 7, "message": {"text": "no chat"}},
{"update_id": 8},
{"update_id": 9, "message": {"chat": {"id": 111}}},
{"update_id": 10, "message": {"chat": {"id": 111}, "text": "explode please"}},
{"update_id": 11, "message": {"chat": {"id": 111}, "text": "long"}},
{"update_id": 12, "message": {"chat": {"id": 111}, "text": "empty reply"}},
{"update_id": 13, "message": {"chat": {"id": 222}, "voice": {"file_id": "f1"}}},
{"update_id": 14, "message": {"chat": {"id": 222}, "audio": {"file_id": "f1"}}},
{"update_id": 15, "message": {"chat": {"id": 222}, "voice": {"file_id": "nofile"}}},
{"update_id": 16, "message": {"chat": {"id": 222}, "voice": {"file_id": "fbad"}}},
{"update_id": 17, "message": {"chat": {"id": 222}, "voice": {"file_id": "fmodel"}}},
{"update_id": 18, "message": {"chat": {"id": 222}, "voice": {}, "text": "text with empty voice"}},
{"update_id": 19, "message": {"chat": {"id": 222}, "voice": {"file_id": "fmissingfile"}}},
{"update_id": 20, "message": {"chat": {"id": "str-chat"}, "text": "string chat id"}},
{"update_id": 21, "message": {"chat": {"id": 111}, "text": "unicode café \U0001f600"}},
]
for update in updates:
out("-- update %s" % j(update))
try:
tai.handle_telegram_update(agent, good, update)
except Exception as exc:
out("raised %s" % j(tai.short_error(exc)))
os.environ["MISC_BOX_FAIL"] = "1"
out("-- box failing")
try:
tai.handle_telegram_update(agent, good, {"update_id": 30, "message": {"chat": {"id": 5}, "voice": {"file_id": "f1"}}})
except Exception as exc:
out("raised %s" % j(tai.short_error(exc)))
os.environ.pop("MISC_BOX_FAIL", None)
out("== run_telegram_bot")
for label, token in (("missing", None), ("bad auth", "bad"), ("not json", "nojson"), ("no username", "noname"), ("good", "good")):
os.environ.pop("TELEGRAM_BOT_TOKEN", None)
if token:
os.environ["TELEGRAM_BOT_TOKEN"] = token
out("-- run %s" % label)
sys.stdout.flush()
def stop_sleep(seconds):
out("sleep %s" % seconds)
raise StopLoop()
tai.time.sleep = stop_sleep
try:
res = tai.run_telegram_bot(agent)
out("returned %s" % res)
except StopLoop:
out("stopped by sleep")
sys.stdout.flush()
sys.stderr.flush()
def sc_telegram_install(root):
tg_setup(root)
home = tai_home()
install_env(root, engine="podman", state="running", venv="venv ready")
for label, token in (("good", "good"), ("bad", "bad"), ("nojson", "nojson"), ("noname", "noname")):
os.environ["TELEGRAM_BOT_TOKEN"] = token
out("-- install_telegram %s" % label)
sys.stdout.flush()
res = tai.install_telegram()
out("returned %s" % res)
out("unit exists %s env exists %s" % (os.path.exists(os.path.join(os.path.expanduser("~"), ".config", "systemd", "user", "tai-telegram.service")), os.path.exists(tai.telegram_env_path(home))))
os.environ.pop("TELEGRAM_BOT_TOKEN", None)
out("-- install_telegram without token (stdin closed)")
sys.stdout.flush()
out("returned %s" % tai.install_telegram())
out("-- install_telegram box failing")
install_env(root, engine="podman", ensure_error="no engine here")
os.environ["TELEGRAM_BOT_TOKEN"] = "good"
out("returned %s" % tai.install_telegram())
install_env(root, engine="podman", state="running", venv="venv ready")
out("-- op_telegram_service")
for token in ("good", "bad", "nojson", "noname"):
os.environ["TELEGRAM_BOT_TOKEN"] = token
for mode in ("install", "install", "reinstall", "upgrade", "uninstall", "uninstall"):
out("service %s %s => %s" % (token, mode, j(tai.op_telegram_service(mode, home).replace(root, "<ROOT>"))))
os.environ.pop("TELEGRAM_BOT_TOKEN", None)
write(tai.telegram_env_path(home), "TELEGRAM_BOT_TOKEN=good\n")
out("service from env file => %s" % j(tai.op_telegram_service("install", home)))
out("-- uninstall_telegram")
out("returned %s" % tai.uninstall_telegram())
install_env(root, engine=None)
out("returned noengine %s" % tai.uninstall_telegram())
# ------------------------------------------------------------------ release / audit scenarios
def prep_release(root):
config, seal, store = open_store()
store.close()
def sc_release(root):
import shutil
config, seal, store = open_store()
script = os.path.join(root, "script.py")
shutil.copy(tai.__file__, script)
tai.__file__ = script
folder = os.path.join(root, "backups")
out("== versions")
for cur, part in (("1.2.3", "patch"), ("1.2.3", "minor"), ("1.2.3", "major"), ("9.9.9", "patch"), ("1.2.3", "bogus"), ("1.2", "patch"), ("a.b.c", "patch"), ("1.2.3.4", "patch")):
try:
out("next %s %s => %s" % (cur, part, tai.next_version(cur, part)))
except Exception as exc:
out("next %s %s => raised %s" % (cur, part, j(str(exc))))
out("== bump")
for part in ("patch", "minor", "major", "patch"):
out("bump %s => %s" % (part, j(tai.release_bump(script, part))))
with open(script, encoding="utf-8") as handle:
text = handle.read()
out("version line %s" % j([l for l in text.splitlines() if l.startswith("VERSION = ")]))
novers = os.path.join(root, "nov.py")
write(novers, "print('x')\n")
for f in (novers, os.path.join(root, "missing.py")):
try:
tai.release_bump(f, "patch")
except Exception as exc:
out("bump error %s" % j(str(exc).replace(root, "<ROOT>")))
write(os.path.join(root, "crlf.py"), 'a\r\nVERSION = "1.0.0"\r\nb\r\n')
out("crlf bump %s %s" % (j(tai.release_bump(os.path.join(root, "crlf.py"), "patch")), j(open(os.path.join(root, "crlf.py"), "rb").read().decode())))
out("== snapshots and pruning")
first, digest = tai.snapshot_self(script, folder, "9.9.9")
out("snapshot %s %s" % (j(os.path.basename(first)), digest))
out("has digest %s %s" % (tai.backup_has_digest(folder, digest), tai.backup_has_digest(folder, "deadbeef")))
out("has digest nofolder %s" % tai.backup_has_digest(os.path.join(root, "nofolder"), digest))
for index in range(14):
name = os.path.join(folder, "tai-0.0.%d-20200101T000000Z-%08d.py" % (index, index))
write(name, "x")
os.utime(name, (1000 + index, 1000 + index))
write(os.path.join(folder, "notes.txt"), "keep")
out("pruned %d" % tai.prune_backups(folder))
out("left %s" % j(sorted(os.listdir(folder))).replace(os.path.basename(first), "<SNAP>"))
out("prune missing %d" % tai.prune_backups(os.path.join(root, "nofolder")))
out("== ensure_self_backup")
shutil.rmtree(folder)
home = tai_home()
first = tai.ensure_self_backup(config, store, script)
out("ensure first %s" % j(os.path.basename(first)))
out("ensure second %s" % j(tai.ensure_self_backup(config, store, script)))
rows = store.db.execute("SELECT actor, action, path, message, old_size, new_size, tags FROM audit ORDER BY id").fetchall()
out("audit %s" % j([list(r) for r in rows]))
out("== do_release")
try:
tai.do_release(store, script, folder, "patch", " ")
except Exception as exc:
out("blank message %s" % j(str(exc)))
res = tai.do_release(store, script, folder, "minor", " ship it ", "tester")
out("do_release %s" % j([res[0], res[1], os.path.basename(res[2]), res[3]]))
out("== release tool")
app = SkillApp(home, root)
app.store = store
app.profile = "t"
tools = tai.Tools(app)
for args in ({"part": "", "message": "m"}, {"part": "patch", "message": ""}, {"part": "huge", "message": "m"}, {"part": "Patch", "message": "tool release"}, {"part": "major", "message": "m" * 300}):
out("release %s => %s" % (j(args), j(tools.dispatch("release", json.dumps(args)).replace(root, "<ROOT>"))))
app.approve = False
out("release denied => %s" % j(tools.dispatch("release", json.dumps({"part": "patch", "message": "no"}))))
app.approve = True
write(script, "nothing here\n")
out("release no version => %s" % j(tools.dispatch("release", json.dumps({"part": "patch", "message": "m"}))))
out("approvals %s" % j(app.approvals))
out("== capped helpers")
out("capped %s" % j([tai.capped_text(None), tai.capped_text("abc"), tai.capped_text("é" * 20001)[1], tai.capped_text("x" * 20001)[0][-60:], tai.trunc_marker(5)]))
big = os.path.join(root, "big.txt")
write(big, "line\r\nsecond\rthird\n" + "é" * 30000)
for cap in (20000, 50, 100000):
r = tai.read_capped(big, cap)
out("read_capped %d => %s %s" % (cap, j(r[0][:40] if r[0] else r[0]), j(r[1])))
write(os.path.join(root, "bad.bin"), "")
with open(os.path.join(root, "bad.bin"), "wb") as handle:
handle.write(b"ok \xff\xfe bad \xc3 end")
out("read_capped invalid %s" % j(tai.read_capped(os.path.join(root, "bad.bin"))))
out("read_capped missing %s" % j(tai.read_capped(os.path.join(root, "missing"))))
store.close()
def prep_audit(root):
config, seal, store = open_store()
store.audit_event("main", "write", os.path.join("area", "a.txt"), "first write", None, "hello\n", ["file", "Doc"], None, None, "t")
store.audit_event("main", "edit", os.path.join("area", "a.txt"), "edit it", "hello\n", "hello world\n", ["file"], None, None, "t")
store.audit_event("main", "delete", os.path.join("area", "a.txt"), "", "hello world\n", None, [], None, None, "t")
store.audit_event("main", "write", os.path.join("area", "big.txt"), "big", None, "B" * 25000, ["file"], None, None, "t")
store.audit_event("main", "write", os.path.join("area", "sized.txt"), "oversize", None, "small", [], None, 99999, "t")
store.audit_event("main", "snapshot", "/x/tai.py", "backed up", None, None, ["snapshot"], None, None, "t")
store.audit_event("main", "release", "/x/tai.py", "released", "1.0.0", "1.0.1", ["release", "v1.0.1"], None, None, "t")
store.audit_event("main", "write", "sandbox:/box/f.txt", "in box", None, "boxed", [], None, None, "t")
store.audit_event("other", "write", "/o/f.txt", "other profile", None, "o", [], None, None, "other")
store.audit_event("main", "write", os.path.join("area", "sub", "deep", "r.txt"), "restore deep", None, "deep content", ["file"], None, None, "t")
store.audit_event("main", "write", os.path.join("area", "u.txt"), "unicode é alpha", None, "café \U0001f600", ["file"], None, None, "t")
store.audit_event("main", "noop", "/n", "no content", None, None, [], None, None, "t")
store.tag_item("mem:t1", ["alpha", "beta"], "t")
store.tag_item("mem:t2", ["alpha"], "t")
store.tag_item("mem:t3", ["a_b", "a%c", "alphabet"], "t")
store.close()
class AuditApp(SkillApp):
def __init__(self, home, root, store):
SkillApp.__init__(self, home, root)
self.store = store
self.profile = "t"
self.env = "home"
def sc_audit(root):
config, seal, store = open_store()
app = AuditApp(tai_home(), root, store)
tools = tai.Tools(app)
def call(name, args):
res = tools.dispatch(name, json.dumps(args))
out("%s %s => %s" % (name, j(args), j(res.replace(root, "<ROOT>"))))
out("== audit")
for args in ({}, {"limit": 3}, {"path": os.path.join("area", "a.txt")}, {"tag": "file"}, {"tag": "nomatch"}, {"query": "alpha"}, {"query": "write"}, {"query": "zzzz"}, {"limit": "x"}, {"limit": 500}, {"query": "unicode"}):
call("audit", args)
out("== tags")
for args in ({}, {"prefix": "al"}, {"prefix": "A_"}, {"prefix": "a%"}, {"prefix": "zzz"}, {"limit": 1}, {"limit": "x"}, {"prefix": " Al "}):
call("tags", args)
out("== restore")
for args in ({}, {"id": "x"}, {"id": 9999}, {"id": 6}, {"id": 7}, {"id": 1}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 12}, {"id": 10}, {"id": 11}):
call("restore", args)
for rel in ("a.txt", "sub/deep/r.txt", "u.txt"):
path = os.path.join("area", rel)
out("file %s %s" % (rel, j(open(path, encoding="utf-8").read() if os.path.exists(path) else None)))
app.approve = False
call("restore", {"id": 2})
app.approve = True
out("approvals %s" % j([a.replace(root, "<ROOT>") for a in app.approvals]))
store.close()
SCENARIOS = {
"release": sc_release,
"audit": sc_audit,
"telegram": sc_telegram,
"telegram_install": sc_telegram_install,
"rag": sc_rag,
"sched": sc_sched,
"install_hooks": sc_install_hooks,
"install_hooks_noshell": sc_install_hooks,
"install_ops": sc_install_ops,
"install_noengine": sc_install_noengine,
"vault_line": sc_vault_line,
"json": sc_json,
"datetime": sc_datetime,
"chunk": sc_chunk,
"fts": sc_fts,
"skills_data": sc_skills_data,
"skills_files": sc_skills_files,
"skills_ops": sc_skills_ops,
}
PREPARE = {"sched": prep_sched, "rag": prep_rag, "release": prep_release, "audit": prep_audit}
def main():
name, root = sys.argv[1], sys.argv[2]
prepare = len(sys.argv) > 3 and sys.argv[3] == "prepare"
os.chdir(os.path.join(root, "proj"))
if prepare:
fn = PREPARE.get(name)
if fn:
fn(root)
return 0
SCENARIOS[name](root)
return 0
if __name__ == "__main__":
sys.exit(main())