{"version":3,"file":"core/AgioBatchProcessor.mjs","sources":["webpack://@agent-tars/server/./src/core/AgioBatchProcessor.ts"],"sourcesContent":["/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AgioEvent } from '@multimodal/agio';\n\n/**\n * Options for configuring the AgioBatchProcessor.\n */\nexport interface AgioBatchProcessorOptions {\n  /**\n   * The URL of the AGIO provider endpoint.\n   */\n  providerUrl: string;\n  /**\n   * The maximum number of events to buffer before sending a batch.\n   * @default 20\n   */\n  maxBatchSize?: number;\n  /**\n   * The maximum time in milliseconds to wait before sending a batch.\n   * @default 5000\n   */\n  flushInterval?: number;\n  /**\n   * The timeout for the fetch request in milliseconds.\n   * @default 5000\n   */\n  requestTimeout?: number;\n}\n\n/**\n * AgioBatchProcessor handles batching and sending of AGIO events.\n *\n * It collects events in a buffer and sends them periodically or when the\n * buffer reaches a certain size, improving performance by reducing the number of\n * HTTP requests.\n */\nexport class AgioBatchProcessor {\n  private readonly providerUrl: string;\n  private readonly maxBatchSize: number;\n  private readonly flushInterval: number;\n  private readonly requestTimeout: number;\n\n  private eventBuffer: AgioEvent.ExtendedEvent[] = [];\n  private timer: NodeJS.Timeout | null = null;\n\n  constructor(options: AgioBatchProcessorOptions) {\n    this.providerUrl = options.providerUrl;\n    this.maxBatchSize = options.maxBatchSize ?? 20;\n    this.flushInterval = options.flushInterval ?? 5000;\n    this.requestTimeout = options.requestTimeout ?? 5000;\n  }\n\n  /**\n   * Adds an event to the buffer.\n   * If the buffer reaches maxBatchSize, it will be flushed immediately.\n   * @param event The AGIO event to add.\n   */\n  public addEvent(event: AgioEvent.ExtendedEvent): void {\n    this.eventBuffer.push(event);\n    if (this.eventBuffer.length >= this.maxBatchSize) {\n      this.flush();\n    } else {\n      this.scheduleFlush();\n    }\n  }\n\n  /**\n   * Manually triggers a flush of the event buffer.\n   * This is useful for ensuring all events are sent, e.g., on application shutdown.\n   */\n  public async flush(): Promise<void> {\n    this.clearScheduledFlush();\n\n    if (this.eventBuffer.length === 0) {\n      return;\n    }\n\n    const eventsToSend = [...this.eventBuffer];\n    this.eventBuffer = [];\n\n    try {\n      const controller = new AbortController();\n      const timeoutId = setTimeout(() => controller.abort(), this.requestTimeout);\n\n      /**\n       * The provider endpoint is designed to accept an array of events\n       * in a single request under the `events` key. This batching mechanism\n       * is crucial for performance in high-throughput environments.\n       */\n      const response = await fetch(this.providerUrl, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({ events: eventsToSend }),\n        signal: controller.signal,\n      });\n\n      clearTimeout(timeoutId);\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n    } catch (error) {\n      if (error instanceof Error && error.name === 'AbortError') {\n        console.error(`AGIO event batch request to ${this.providerUrl} timed out`);\n      } else {\n        console.error(`Failed to send AGIO event batch to ${this.providerUrl}:`, error);\n      }\n      // Optional: Add events back to the buffer for retry, or handle them in a dead-letter queue.\n      // For simplicity, we are currently dropping them.\n    }\n  }\n\n  /**\n   * Schedules a flush if one isn't already scheduled.\n   */\n  private scheduleFlush(): void {\n    if (!this.timer) {\n      this.timer = setTimeout(() => {\n        this.flush();\n      }, this.flushInterval);\n    }\n  }\n\n  /**\n   * Clears any scheduled flush.\n   */\n  private clearScheduledFlush(): void {\n    if (this.timer) {\n      clearTimeout(this.timer);\n      this.timer = null;\n    }\n  }\n}\n"],"names":["AgioBatchProcessor","event","eventsToSend","controller","AbortController","timeoutId","setTimeout","response","fetch","JSON","clearTimeout","Error","error","console","options"],"mappings":";;;;AAGC;;;;;;;;;;AAoCM,MAAMA;IAqBJ,SAASC,KAA8B,EAAQ;QACpD,IAAI,CAAC,WAAW,CAAC,IAAI,CAACA;QACtB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAC9C,IAAI,CAAC,KAAK;aAEV,IAAI,CAAC,aAAa;IAEtB;IAMA,MAAa,QAAuB;QAClC,IAAI,CAAC,mBAAmB;QAExB,IAAI,AAA4B,MAA5B,IAAI,CAAC,WAAW,CAAC,MAAM,EACzB;QAGF,MAAMC,eAAe;eAAI,IAAI,CAAC,WAAW;SAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,EAAE;QAErB,IAAI;YACF,MAAMC,aAAa,IAAIC;YACvB,MAAMC,YAAYC,WAAW,IAAMH,WAAW,KAAK,IAAI,IAAI,CAAC,cAAc;YAO1E,MAAMI,WAAW,MAAMC,MAAM,IAAI,CAAC,WAAW,EAAE;gBAC7C,QAAQ;gBACR,SAAS;oBACP,gBAAgB;gBAClB;gBACA,MAAMC,KAAK,SAAS,CAAC;oBAAE,QAAQP;gBAAa;gBAC5C,QAAQC,WAAW,MAAM;YAC3B;YAEAO,aAAaL;YAEb,IAAI,CAACE,SAAS,EAAE,EACd,MAAM,IAAII,MAAM,CAAC,oBAAoB,EAAEJ,SAAS,MAAM,EAAE;QAE5D,EAAE,OAAOK,OAAO;YACd,IAAIA,iBAAiBD,SAASC,AAAe,iBAAfA,MAAM,IAAI,EACtCC,QAAQ,KAAK,CAAC,CAAC,4BAA4B,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;iBAEzEA,QAAQ,KAAK,CAAC,CAAC,mCAAmC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAED;QAI7E;IACF;IAKQ,gBAAsB;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,EACb,IAAI,CAAC,KAAK,GAAGN,WAAW;YACtB,IAAI,CAAC,KAAK;QACZ,GAAG,IAAI,CAAC,aAAa;IAEzB;IAKQ,sBAA4B;QAClC,IAAI,IAAI,CAAC,KAAK,EAAE;YACdI,aAAa,IAAI,CAAC,KAAK;YACvB,IAAI,CAAC,KAAK,GAAG;QACf;IACF;IAxFA,YAAYI,OAAkC,CAAE;QARhD,uBAAiB,eAAjB;QACA,uBAAiB,gBAAjB;QACA,uBAAiB,iBAAjB;QACA,uBAAiB,kBAAjB;QAEA,uBAAQ,eAAyC,EAAE;QACnD,uBAAQ,SAA+B;QAGrC,IAAI,CAAC,WAAW,GAAGA,QAAQ,WAAW;QACtC,IAAI,CAAC,YAAY,GAAGA,QAAQ,YAAY,IAAI;QAC5C,IAAI,CAAC,aAAa,GAAGA,QAAQ,aAAa,IAAI;QAC9C,IAAI,CAAC,cAAc,GAAGA,QAAQ,cAAc,IAAI;IAClD;AAoFF"}