#!/usr/bin/env python3 """ Uses the agent service to answer a question """ import argparse import os import textwrap import uuid import asyncio import json from websockets.asyncio.client import connect default_url = os.getenv("TRUSTGRAPH_URL", 'ws://localhost:8088/') default_user = 'trustgraph' default_collection = 'default' def wrap(text, width=75): if text is None: text = "n/a" out = textwrap.wrap( text, width=width ) return "\n".join(out) def output(text, prefix="> ", width=78): out = textwrap.indent( text, prefix=prefix ) print(out) async def question( url, question, flow_id, user, collection, plan=None, state=None, verbose=False ): if not url.endswith("/"): url += "/" url = url + "api/v1/socket" if verbose: output(wrap(question), "\U00002753 ") print() def think(x): if verbose: output(wrap(x), "\U0001f914 ") print() def observe(x): if verbose: output(wrap(x), "\U0001f4a1 ") print() mid = str(uuid.uuid4()) async with connect(url) as ws: req = json.dumps({ "id": mid, "service": "agent", "flow": flow_id, "request": { "question": question, } }) await ws.send(req) while True: msg = await ws.recv() obj = json.loads(msg) if "error" in obj: raise RuntimeError(obj["error"]) if obj["id"] != mid: print("Ignore message") continue if "thought" in obj["response"]: think(obj["response"]["thought"]) if "observation" in obj["response"]: observe(obj["response"]["observation"]) if "answer" in obj["response"]: print(obj["response"]["answer"]) if obj["complete"]: break await ws.close() def main(): parser = argparse.ArgumentParser( prog='tg-invoke-agent', description=__doc__, ) parser.add_argument( '-u', '--url', default=default_url, help=f'API URL (default: {default_url})', ) parser.add_argument( '-f', '--flow-id', default="0000", help=f'Flow ID (default: 0000)' ) parser.add_argument( '-q', '--question', required=True, help=f'Question to answer', ) parser.add_argument( '-U', '--user', default=default_user, help=f'User ID (default: {default_user})' ) parser.add_argument( '-C', '--collection', default=default_collection, help=f'Collection ID (default: {default_collection})' ) parser.add_argument( '-l', '--plan', help=f'Agent plan (default: unspecified)' ) parser.add_argument( '-s', '--state', help=f'Agent initial state (default: unspecified)' ) parser.add_argument( '-v', '--verbose', action="store_true", help=f'Output thinking/observations' ) args = parser.parse_args() try: asyncio.run( question( url = args.url, flow_id = args.flow_id, question = args.question, user = args.user, collection = args.collection, plan = args.plan, state = args.state, verbose = args.verbose, ) ) except Exception as e: print("Exception:", e, flush=True) main()