feat: scaffold watch-screen AI pipeline (mock-runnable skeleton)
Modular async pipeline: FrameSource->Vision->context and STT/text->Brain->TTS. All stages are Protocols; mock backends run end-to-end with no deps/keys. Real backends included: mss screen capture, Claude vision+brain (guarded imports).
This commit is contained in:
62
wsai/__main__.py
Normal file
62
wsai/__main__.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""Entry point.
|
||||
|
||||
python -m wsai # mock pipeline (no deps, no keys) — runs a demo
|
||||
python -m wsai --live # capture this screen + Claude eyes/brain
|
||||
python -m wsai --env # build from WSAI_* environment variables
|
||||
|
||||
The mock run is bounded (a few frames + a scripted conversation) so it exits on
|
||||
its own; --live/--env run until Ctrl-C.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from .config import Settings
|
||||
from .factory import build
|
||||
|
||||
|
||||
async def _run(settings: Settings, demo: bool) -> None:
|
||||
if demo:
|
||||
# Bounded demo so CI / a quick check terminates.
|
||||
from .backends.mock import MockFrameSource, MockSTT
|
||||
from .pipeline import Pipeline
|
||||
|
||||
pipe = build(settings)
|
||||
pipe.source = MockFrameSource(interval=0.3, limit=4)
|
||||
if pipe.stt is not None:
|
||||
pipe.stt = MockSTT(interval=0.4)
|
||||
await pipe.run()
|
||||
return
|
||||
await build(settings).run()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ap = argparse.ArgumentParser(prog="wsai")
|
||||
ap.add_argument("--live", action="store_true", help="capture screen + Claude backends")
|
||||
ap.add_argument("--env", action="store_true", help="build from WSAI_* env vars")
|
||||
ap.add_argument("-v", "--verbose", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG if args.verbose else logging.INFO,
|
||||
format="%(levelname)s %(name)s: %(message)s",
|
||||
)
|
||||
|
||||
if args.live:
|
||||
settings, demo = Settings.live(), False
|
||||
elif args.env:
|
||||
settings, demo = Settings.from_env(), False
|
||||
else:
|
||||
settings, demo = Settings.mock(), True
|
||||
|
||||
try:
|
||||
asyncio.run(_run(settings, demo))
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user