You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.py 3.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #! /bin/env python3
  2. import os
  3. import argparse
  4. from revChatGPT.V1 import Chatbot
  5. from typing import List
  6. from marko.parser import Parser
  7. from marko.block import FencedCode
  8. from marko.inline import RawText
  9. ENV_UUID = "GPTTRACE_CONV_UUID"
  10. ENV_ACCESS_TOKEN = "GPTTRACE_ACCESS_TOKEN"
  11. def main():
  12. parser = argparse.ArgumentParser(
  13. prog='GPTtrace',
  14. description='Use ChatGPT to write eBPF programs (bpftrace, etc.)')
  15. group = parser.add_mutually_exclusive_group()
  16. group.add_argument(
  17. "-e", "--explain", help="Let ChatGPT explain what's eBPF", action="store_true")
  18. group.add_argument(
  19. "-v", "--verbose", help="Print the receive ", action="store_true")
  20. group.add_argument(
  21. "-r", "--run", help="Generate commands using your input with ChatGPT, and run it", action="store", metavar="TEXT")
  22. parser.add_argument(
  23. "-u", "--uuid", help=f"Conversion UUID to use, or passed through environment variable `{ENV_UUID}`")
  24. parser.add_argument("-t", "--access-token",
  25. help=f"ChatGPT access token, see `https://chat.openai.com/api/auth/session` or passed through `{ENV_ACCESS_TOKEN}`")
  26. args = parser.parse_args()
  27. if (args.explain or args.run) is None:
  28. parser.print_help()
  29. return
  30. access_token = args.access_token or os.environ.get(ENV_ACCESS_TOKEN, None)
  31. conv_uuid = args.uuid or os.environ.get(ENV_UUID, None)
  32. if access_token is None:
  33. print(
  34. f"Either provide your access token through `-t` or through environment variable {ENV_ACCESS_TOKEN}")
  35. return
  36. chatbot = Chatbot(config={"access_token": access_token})
  37. if args.explain:
  38. generate_result(chatbot, "Explain what's eBPF", conv_uuid, True)
  39. elif args.run is not None:
  40. desc: str = args.run
  41. print("Sending query to ChatGPT: " + desc)
  42. ret_val = generate_result(chatbot, construct_prompt(desc), conv_uuid, args.verbose)
  43. # print(ret_val)
  44. parsed = make_executable_command(ret_val)
  45. # print(f"Command to run: {parsed}")
  46. print("Press Ctrl+C to stop the program....")
  47. os.system("sudo " + parsed)
  48. def construct_prompt(text: str) -> str:
  49. return f'''You are now a translater from human language to {os.uname()[0]} shell bpftrace command.
  50. No explanation required.
  51. respond with only the raw shell bpftrace command.
  52. It should be start with `bpftrace`.
  53. Your response should be able to put into a shell and run directly.
  54. Just output in one line, without any description, or any other text that cannot be run in shell.
  55. What should I type to shell to trace using bpftrace for: {text}, in one line.'''
  56. def make_executable_command(command: str) -> str:
  57. if command.startswith('\n'):
  58. command = command[1:]
  59. if command.endswith('\n'):
  60. command = command[:-1]
  61. if command.startswith('`'):
  62. command = command[1:]
  63. if command.endswith('`'):
  64. command = command[:-1]
  65. command = command.strip()
  66. command = command.split('User: ')[0]
  67. return command
  68. def generate_result(bot: Chatbot, text: str, session: str = None, print_out: bool = False) -> str:
  69. from io import StringIO
  70. prev_text = ""
  71. buf = StringIO()
  72. for data in bot.ask(
  73. text, conversation_id=session
  74. ):
  75. message = data["message"][len(prev_text):]
  76. if print_out:
  77. print(message, end="", flush=True)
  78. buf.write(message)
  79. prev_text = data["message"]
  80. if print_out:
  81. print()
  82. return buf.getvalue()
  83. def extract_code_blocks(text: str) -> List[str]:
  84. result = []
  85. parser = Parser()
  86. for block in parser.parse(text).children:
  87. if type(block) is FencedCode:
  88. block: FencedCode
  89. blk: RawText = block.children[0]
  90. result.append(blk.children)
  91. return result
  92. if __name__ == "__main__":
  93. main()

Generate eBPF programs and tracing with ChatGPT and natural language