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.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. "-r", "--run", help="Generate commands using your input with ChatGPT, and run it", action="store", metavar="TEXT")
  20. parser.add_argument(
  21. "-u", "--uuid", help=f"Conversion UUID to use, or passed through environment variable `{ENV_UUID}`")
  22. parser.add_argument("-t", "--access-token",
  23. help=f"ChatGPT access token, see `https://chat.openai.com/api/auth/session` or passed through `{ENV_ACCESS_TOKEN}`")
  24. args = parser.parse_args()
  25. if (args.explain or args.run) is None:
  26. parser.print_help()
  27. return
  28. access_token = args.access_token or os.environ.get(ENV_ACCESS_TOKEN, None)
  29. conv_uuid = args.uuid or os.environ.get(ENV_UUID, None)
  30. if access_token is None:
  31. print(
  32. f"Either provide your access token through `-t` or through environment variable {ENV_ACCESS_TOKEN}")
  33. return
  34. chatbot = Chatbot(config={"access_token": access_token})
  35. if args.explain:
  36. generate_result(chatbot, "解释一下什么是 eBPF", conv_uuid, True)
  37. elif args.run is not None:
  38. desc: str = args.run
  39. ret_val = generate_result(chatbot, desc, conv_uuid, True)
  40. # print(ret_val)
  41. parsed = make_executable_command(ret_val)
  42. print(f"Command to run: {parsed}")
  43. os.system("sudo " + parsed)
  44. def construct_prompt(text: str) -> str:
  45. return f'''You are now a translater from human language to {os.uname()[0]} shell bpftrace command.
  46. No explanation required.
  47. respond with only the raw shell bpftrace command.
  48. It should be start with `bpftrace`.
  49. Your response should be able to put into a shell and run directly.
  50. Just output in one line, without any description, or any other text that cannot be run in shell.
  51. What should I type to shell to trace using bpftrace for: {text}, in one line.'''
  52. def make_executable_command(command: str) -> str:
  53. if command.startswith('\n'):
  54. command = command[1:]
  55. if command.endswith('\n'):
  56. command = command[:-1]
  57. if command.startswith('`'):
  58. command = command[1:]
  59. if command.endswith('`'):
  60. command = command[:-1]
  61. command = command.strip()
  62. command = command.split('User: ')[0]
  63. return command
  64. def generate_result(bot: Chatbot, text: str, session: str = None, print_out: bool = False) -> str:
  65. from io import StringIO
  66. prev_text = ""
  67. query_text = construct_prompt(text)
  68. buf = StringIO()
  69. for data in bot.ask(
  70. query_text, conversation_id=session
  71. ):
  72. message = data["message"][len(prev_text):]
  73. if print_out:
  74. print(message, end="", flush=True)
  75. buf.write(message)
  76. prev_text = data["message"]
  77. if print_out:
  78. print()
  79. return buf.getvalue()
  80. def extract_code_blocks(text: str) -> List[str]:
  81. result = []
  82. parser = Parser()
  83. for block in parser.parse(text).children:
  84. if type(block) is FencedCode:
  85. block: FencedCode
  86. blk: RawText = block.children[0]
  87. result.append(blk.children)
  88. return result
  89. if __name__ == "__main__":
  90. main()

Generate eBPF programs and tracing with ChatGPT and natural language