File size: 3,419 Bytes
713b429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""The `jev-interaction` command.

    jev-interaction serve [--host 127.0.0.1] [--port 8080] [--preset production] [--home .]
    jev-interaction init [--reference global|china]   write .env (empty, or a reference setup's values) and profiles/
    jev-interaction replay runs/*.jsonl --purpose floor [--edit my_questions.py]
"""
from __future__ import annotations

import argparse
import os
import pathlib
import sys


def _serve(a: argparse.Namespace) -> int:
    try:
        import uvicorn
    except ImportError:
        print('The server needs its extras:  pip install "jev-interaction[server]"', file=sys.stderr)
        return 1
    if a.home:
        os.environ["JEV_HOME"] = str(pathlib.Path(a.home).resolve())
    if a.preset:
        os.environ["JEV_PRESET"] = a.preset
    from jev_interaction.server import paths
    if not paths.env_file().exists():
        print(f"No .env in {paths.home()} yet: the page walks you through the providers and keys.")
    print(f"Jev-Interaction on http://{'localhost' if a.host in ('127.0.0.1', '0.0.0.0') else a.host}:{a.port}")
    uvicorn.run("jev_interaction.server.app:app", host=a.host, port=a.port, log_level="warning" if a.quiet else "info")
    return 0


def _init(a: argparse.Namespace) -> int:
    from jev_interaction.server import paths, settings
    home = pathlib.Path(a.home or os.getcwd()).resolve()
    os.environ["JEV_HOME"] = str(home)
    env = paths.env_file()
    if env.exists():
        print(f"{env} already exists; leaving it alone.")
    else:
        t = settings.TEMPLATES[a.reference] if a.reference else {}
        keys = sorted(settings.SECRETS)
        body = ["# Jev-Interaction settings. Fill them in here, or follow the setup steps on the page."]
        body += [f"{k}=" for k in keys] + [f"{k}={v}" for k, v in t.items()]
        env.write_text("\n".join(body) + "\n", encoding="utf-8")
        env.chmod(0o600)
        print(f"Wrote {env}")
    (home / "profiles").mkdir(exist_ok=True)
    print(f"Your own personas go in {home / 'profiles'} (copy one from {paths.PACKAGE / 'profiles'} to start).")
    return 0


def main(argv: list[str] | None = None) -> int:
    ap = argparse.ArgumentParser(prog="jev-interaction", description="Full-duplex voice calls, turn-taking judged by Jev.")
    sub = ap.add_subparsers(dest="cmd", required=True)
    s = sub.add_parser("serve", help="run the call server and its page")
    s.add_argument("--host", default="127.0.0.1")
    s.add_argument("--port", type=int, default=int(os.getenv("PORT", "8080")))
    s.add_argument("--preset", help="production | tested | default (overrides JEV_PRESET)")
    s.add_argument("--home", help="working folder for .env, runs/ and profiles/ (default: here)")
    s.add_argument("--quiet", action="store_true")
    s.set_defaults(run=_serve)
    i = sub.add_parser("init", help="write a .env template and a profiles/ folder")
    i.add_argument("--reference", choices=["global", "china"], help="start from a reference setup (what we run / mainland China)")
    i.add_argument("--home")
    i.set_defaults(run=_init)
    r = sub.add_parser("replay", help="re-ask the decisions recorded in call logs, as asked or reworded")
    from jev_interaction import replay as R
    R.add_arguments(r)
    r.set_defaults(run=lambda a: __import__("asyncio").run(R.run(a)))
    a = ap.parse_args(argv)
    return a.run(a)


if __name__ == "__main__":
    sys.exit(main())