- Complete Cloudflare Terraform configuration (DNS, WAF, tunnels, access) - WAF Intelligence MCP server with threat analysis and ML classification - GitOps automation with PR workflows and drift detection - Observatory monitoring stack with Prometheus/Grafana - IDE operator rules for governed development - Security playbooks and compliance frameworks - Autonomous remediation and state reconciliation
135 lines
3.4 KiB
Python
135 lines
3.4 KiB
Python
"""
|
|
Command-line interface for oracle_answer tool.
|
|
|
|
Uses NVIDIA's free API (build.nvidia.com) for actual LLM responses.
|
|
|
|
NOTE FOR AUTOMATION:
|
|
- All CLI arguments must be defined ONLY in build_parser().
|
|
- When changing CLI flags, rewrite build_parser() entirely.
|
|
- Do not define duplicate flags like --question in other functions.
|
|
"""
|
|
|
|
import argparse
|
|
import asyncio
|
|
import json
|
|
import sys
|
|
from typing import List, Optional
|
|
|
|
from .tool import OracleAnswerTool
|
|
|
|
|
|
def build_parser() -> argparse.ArgumentParser:
|
|
"""
|
|
Build argument parser.
|
|
|
|
RULE: This function is the single source of truth for CLI args.
|
|
Never append args elsewhere.
|
|
"""
|
|
parser = argparse.ArgumentParser(
|
|
prog="oracle-answer",
|
|
description="Sovereign compliance oracle powered by NVIDIA AI.",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog="""
|
|
Examples:
|
|
oracle-answer --question "Are we GDPR compliant?" --frameworks GDPR ISO-27001
|
|
oracle-answer --question "Incident response time SLA?" --mode advisory
|
|
oracle-answer --question "Test?" --local-only (skip NVIDIA API)
|
|
""",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--question",
|
|
required=True,
|
|
type=str,
|
|
help="Compliance / security question to answer.",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--frameworks",
|
|
nargs="*",
|
|
default=["NIST-CSF", "ISO-27001"],
|
|
type=str,
|
|
help="Frameworks to reference (space-separated).",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--mode",
|
|
default="strict",
|
|
choices=["strict", "advisory"],
|
|
help="strict = conservative, advisory = more exploratory.",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--json",
|
|
action="store_true",
|
|
help="Output ToolResponse as JSON instead of pretty text.",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--local-only",
|
|
action="store_true",
|
|
help="Skip NVIDIA API calls (for testing).",
|
|
)
|
|
|
|
return parser
|
|
|
|
|
|
async def main_async(args: Optional[List[str]] = None) -> int:
|
|
"""Async main entry point."""
|
|
parser = build_parser()
|
|
ns = parser.parse_args(args=args)
|
|
|
|
tool = OracleAnswerTool(
|
|
default_frameworks=ns.frameworks,
|
|
use_local_only=ns.local_only,
|
|
)
|
|
resp = await tool.answer(
|
|
question=ns.question,
|
|
frameworks=ns.frameworks,
|
|
mode=ns.mode,
|
|
)
|
|
|
|
if ns.json:
|
|
print(
|
|
json.dumps(
|
|
{
|
|
"answer": resp.answer,
|
|
"framework_hits": resp.framework_hits,
|
|
"reasoning": resp.reasoning,
|
|
"model": resp.model,
|
|
},
|
|
indent=2,
|
|
)
|
|
)
|
|
else:
|
|
print("\n" + "=" * 80)
|
|
print("ORACLE ANSWER (Powered by NVIDIA AI)")
|
|
print("=" * 80 + "\n")
|
|
print(resp.answer)
|
|
if resp.reasoning:
|
|
print("\n--- Reasoning ---\n")
|
|
print(resp.reasoning)
|
|
if resp.framework_hits:
|
|
print("\n--- Framework Hits ---\n")
|
|
for framework, hits in resp.framework_hits.items():
|
|
if hits:
|
|
print(f"{framework}:")
|
|
for hit in hits:
|
|
print(f" • {hit}")
|
|
print(f"\n[Model: {resp.model}]")
|
|
print()
|
|
|
|
return 0
|
|
|
|
|
|
def main() -> None:
|
|
"""Sync wrapper for CLI entry point."""
|
|
try:
|
|
sys.exit(asyncio.run(main_async()))
|
|
except KeyboardInterrupt:
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|