File size: 3,891 Bytes
634117a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""
kerdos_rag/cli.py
Command-line interface for the Kerdos RAG engine.

    kerdos-rag serve          # start Gradio UI  (default port 7860)
    kerdos-rag api            # start FastAPI REST server  (default port 8000)
    kerdos-rag index <files>  # index documents from terminal
"""

from __future__ import annotations

import argparse
import sys


def _cmd_serve(args: argparse.Namespace) -> None:
    """Launch the Gradio web UI."""
    import importlib.util, os

    os.environ.setdefault("GRADIO_SERVER_PORT", str(args.port))
    os.environ.setdefault("GRADIO_SERVER_NAME", args.host)

    # app.py lives at the repo root — import it as a module
    spec = importlib.util.spec_from_file_location("app", _repo_root() / "app.py")
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    mod.demo.queue()
    mod.demo.launch(css=mod.CSS, theme=__import__("gradio").themes.Soft())


def _cmd_api(args: argparse.Namespace) -> None:
    """Launch the FastAPI REST server."""
    import uvicorn
    from kerdos_rag.server import app  # noqa: F401

    print(f"[kerdos-rag] Starting REST API on http://{args.host}:{args.port}")
    uvicorn.run(
        "kerdos_rag.server:app",
        host=args.host,
        port=args.port,
        reload=args.reload,
        log_level="info",
    )


def _cmd_index(args: argparse.Namespace) -> None:
    """Index documents from the command line and print a summary."""
    from kerdos_rag import KerdosRAG

    engine = KerdosRAG()  # token not needed for pure indexing
    result = engine.index(args.files)

    if result["indexed"]:
        print(f"✅ Indexed: {', '.join(result['indexed'])}")
    if result["skipped"]:
        print(f"⚠️  Skipped (already indexed): {', '.join(result['skipped'])}")
    print(f"📦 Total chunks: {result['chunk_count']}")

    if args.save:
        engine.save(args.save)
        print(f"💾 Index saved to: {args.save}")


def _repo_root():
    """Return the directory containing this package."""
    from pathlib import Path
    return Path(__file__).resolve().parent.parent


def main(argv: list[str] | None = None) -> None:
    parser = argparse.ArgumentParser(
        prog="kerdos-rag",
        description="Kerdos RAG — Enterprise Document Q&A engine",
    )
    sub = parser.add_subparsers(dest="command", required=True)

    # ── serve ────────────────────────────────────────────────────────────────
    p_serve = sub.add_parser("serve", help="Start the Gradio web UI")
    p_serve.add_argument("--host", default="0.0.0.0")
    p_serve.add_argument("--port", type=int, default=7860)
    p_serve.set_defaults(func=_cmd_serve)

    # ── api ──────────────────────────────────────────────────────────────────
    p_api = sub.add_parser("api", help="Start the FastAPI REST server")
    p_api.add_argument("--host", default="0.0.0.0")
    p_api.add_argument("--port", type=int, default=8000)
    p_api.add_argument("--reload", action="store_true", help="Enable auto-reload (dev only)")
    p_api.set_defaults(func=_cmd_api)

    # ── index ─────────────────────────────────────────────────────────────────
    p_idx = sub.add_parser("index", help="Index documents from the terminal")
    p_idx.add_argument("files", nargs="+", metavar="FILE")
    p_idx.add_argument("--save", metavar="DIR", default="", help="Save index to directory")
    p_idx.set_defaults(func=_cmd_index)

    args = parser.parse_args(argv)
    args.func(args)


if __name__ == "__main__":
    main()