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

87 lines
2.5 KiB

11 months ago
  1. const chalk = require("chalk");
  2. const { RetryError } = require("../error");
  3. const { Telemetry } = require("../../../../models/telemetry");
  4. /**
  5. * HTTP Interface plugin for Aibitat to emulate a websocket interface in the agent
  6. * framework so we dont have to modify the interface for passing messages and responses
  7. * in REST or WSS.
  8. */
  9. const httpSocket = {
  10. name: "httpSocket",
  11. startupConfig: {
  12. params: {
  13. handler: {
  14. required: true,
  15. },
  16. muteUserReply: {
  17. required: false,
  18. default: true,
  19. },
  20. introspection: {
  21. required: false,
  22. default: true,
  23. },
  24. },
  25. },
  26. plugin: function ({
  27. handler,
  28. muteUserReply = true, // Do not post messages to "USER" back to frontend.
  29. introspection = false, // when enabled will attach socket to Aibitat object with .introspect method which reports status updates to frontend.
  30. }) {
  31. return {
  32. name: this.name,
  33. setup(aibitat) {
  34. aibitat.onError(async (error) => {
  35. if (!!error?.message) {
  36. console.error(chalk.red(` error: ${error.message}`), error);
  37. aibitat.introspect(
  38. `Error encountered while running: ${error.message}`
  39. );
  40. }
  41. if (error instanceof RetryError) {
  42. console.error(chalk.red(` retrying in 60 seconds...`));
  43. setTimeout(() => {
  44. aibitat.retry();
  45. }, 60_000);
  46. return;
  47. }
  48. });
  49. aibitat.introspect = (messageText) => {
  50. if (!introspection) return; // Dump thoughts when not wanted.
  51. handler.send(
  52. JSON.stringify({ type: "statusResponse", content: messageText })
  53. );
  54. };
  55. // expose function for sockets across aibitat
  56. // type param must be set or else msg will not be shown or handled in UI.
  57. aibitat.socket = {
  58. send: (type = "__unhandled", content = "") => {
  59. handler.send(JSON.stringify({ type, content }));
  60. },
  61. };
  62. // We can only receive one message response with HTTP
  63. // so we end on first response.
  64. aibitat.onMessage((message) => {
  65. if (message.from !== "USER")
  66. Telemetry.sendTelemetry("agent_chat_sent");
  67. if (message.from === "USER" && muteUserReply) return;
  68. handler.send(JSON.stringify(message));
  69. handler.close();
  70. });
  71. aibitat.onTerminate(() => {
  72. handler.close();
  73. });
  74. },
  75. };
  76. },
  77. };
  78. module.exports = {
  79. httpSocket,
  80. };