{"version":3,"file":"splitStream.mjs","sources":["../../src/splitStream.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type * as t from '@/types';\nimport { ContentTypes, GraphEvents, StepTypes } from '@/common';\n\nexport const SEPARATORS = [\n  '. ',\n  '?',\n  '!',\n  '۔',\n  '- ',\n  '。',\n  '‥',\n  ';',\n  '¡',\n  '¿',\n  '\\n',\n  '```',\n];\n\nexport class SplitStreamHandler {\n  private inCodeBlock = false;\n  private inThinkBlock = false;\n  private accumulate: boolean;\n  tokens: string[] = [];\n  lastToken = '';\n  reasoningTokens: string[] = [];\n  currentStepId?: string;\n  currentMessageId?: string;\n  currentType?: ContentTypes.TEXT | ContentTypes.THINK;\n  currentLength = 0;\n  reasoningKey: 'reasoning_content' | 'reasoning' = 'reasoning_content';\n  currentIndex = -1;\n  blockThreshold = 4500;\n  /** The run ID AKA the Message ID associated with the complete generation */\n  runId: string;\n  handlers?: t.SplitStreamHandlers;\n  constructor({\n    runId,\n    handlers,\n    accumulate,\n    reasoningKey,\n    blockThreshold,\n  }: {\n    runId: string;\n    accumulate?: boolean;\n    handlers: t.SplitStreamHandlers;\n    blockThreshold?: number;\n    reasoningKey?: 'reasoning_content' | 'reasoning';\n  }) {\n    this.runId = runId;\n    this.handlers = handlers;\n    if (reasoningKey) {\n      this.reasoningKey = reasoningKey;\n    }\n    if (blockThreshold != null) {\n      this.blockThreshold = blockThreshold;\n    }\n    this.accumulate = accumulate ?? false;\n  }\n  getMessageId = (): string | undefined => {\n    const messageId = this.currentMessageId;\n    if (messageId != null && messageId) {\n      return messageId;\n    }\n    return undefined;\n  };\n  createMessageStep = (\n    type?: ContentTypes.TEXT | ContentTypes.THINK\n  ): [string, string] => {\n    if (type != null && this.currentType !== type) {\n      this.currentType = type;\n    }\n    this.currentLength = 0;\n    this.currentIndex += 1;\n    this.currentStepId = `step_${nanoid()}`;\n    this.currentMessageId = `msg_${nanoid()}`;\n    return [this.currentStepId, this.currentMessageId];\n  };\n  dispatchRunStep = (stepId: string, stepDetails: t.StepDetails): void => {\n    const runStep: t.RunStep = {\n      id: stepId,\n      runId: this.runId,\n      type: stepDetails.type,\n      index: this.currentIndex,\n      stepDetails,\n      // usage: null,\n    };\n    this.handlers?.[GraphEvents.ON_RUN_STEP]?.({\n      event: GraphEvents.ON_RUN_STEP,\n      data: runStep,\n    });\n  };\n  dispatchMessageDelta = (stepId: string, delta: t.MessageDelta): void => {\n    const messageDelta: t.MessageDeltaEvent = {\n      id: stepId,\n      delta,\n    };\n    this.handlers?.[GraphEvents.ON_MESSAGE_DELTA]?.({\n      event: GraphEvents.ON_MESSAGE_DELTA,\n      data: messageDelta,\n    });\n  };\n  dispatchReasoningDelta = (stepId: string, delta: t.ReasoningDelta): void => {\n    const reasoningDelta: t.ReasoningDeltaEvent = {\n      id: stepId,\n      delta,\n    };\n    this.handlers?.[GraphEvents.ON_REASONING_DELTA]?.({\n      event: GraphEvents.ON_REASONING_DELTA,\n      data: reasoningDelta,\n    });\n  };\n  handleContent = (\n    content: string,\n    _type: ContentTypes.TEXT | ContentTypes.THINK\n  ): void => {\n    let type = _type;\n    if (this.inThinkBlock && type === ContentTypes.TEXT) {\n      type = ContentTypes.THINK;\n    }\n    if (this.accumulate) {\n      if (type === ContentTypes.THINK) {\n        this.reasoningTokens.push(content);\n      } else {\n        this.tokens.push(content);\n      }\n    }\n\n    if (this.currentType !== type) {\n      const [newStepId, newMessageId] = this.createMessageStep(type);\n      this.dispatchRunStep(newStepId, {\n        type: StepTypes.MESSAGE_CREATION,\n        message_creation: {\n          message_id: newMessageId,\n        },\n      });\n    }\n\n    const stepId = this.currentStepId ?? '';\n    if (type === ContentTypes.THINK) {\n      this.dispatchReasoningDelta(stepId, {\n        content: [\n          {\n            type: ContentTypes.THINK,\n            think: content,\n          },\n        ],\n      });\n    } else {\n      this.dispatchMessageDelta(stepId, {\n        content: [\n          {\n            type: ContentTypes.TEXT,\n            text: content,\n          },\n        ],\n      });\n    }\n\n    this.currentLength += content.length;\n    if (this.inCodeBlock) {\n      return;\n    }\n\n    if (\n      this.currentLength > this.blockThreshold &&\n      SEPARATORS.some((sep) => content.includes(sep))\n    ) {\n      const [newStepId, newMessageId] = this.createMessageStep(type);\n      this.dispatchRunStep(newStepId, {\n        type: StepTypes.MESSAGE_CREATION,\n        message_creation: {\n          message_id: newMessageId,\n        },\n      });\n    }\n  };\n  getDeltaContent(chunk?: t.CustomChunk): string {\n    return (chunk?.choices?.[0]?.delta as t.CustomChunkDelta)?.content ?? '';\n  }\n  getReasoningDelta(chunk?: t.CustomChunk): string {\n    return (\n      (chunk?.choices?.[0]?.delta as t.CustomChunkDelta)?.[this.reasoningKey] ??\n      ''\n    );\n  }\n  handle(chunk?: t.CustomChunk): void {\n    if (!chunk) {\n      return;\n    }\n\n    const content = this.getDeltaContent(chunk);\n    const reasoning_content = this.getReasoningDelta(chunk);\n    if (!content.length && !reasoning_content.length) {\n      return;\n    }\n\n    if (content.includes('```')) {\n      this.inCodeBlock = !this.inCodeBlock;\n    }\n\n    if (content.includes('<think>') && !this.inCodeBlock) {\n      this.inThinkBlock = true;\n    } else if (this.lastToken.includes('</think>') && !this.inCodeBlock) {\n      this.inThinkBlock = false;\n    }\n\n    this.lastToken = content;\n\n    const message_id = this.getMessageId() ?? '';\n\n    if (!message_id) {\n      const initialContentType = this.inThinkBlock\n        ? ContentTypes.THINK\n        : ContentTypes.TEXT;\n      const initialType = reasoning_content\n        ? ContentTypes.THINK\n        : initialContentType;\n      const [stepId, message_id] = this.createMessageStep(initialType);\n      this.dispatchRunStep(stepId, {\n        type: StepTypes.MESSAGE_CREATION,\n        message_creation: {\n          message_id,\n        },\n      });\n    }\n\n    if (reasoning_content) {\n      this.handleContent(reasoning_content, ContentTypes.THINK);\n    } else {\n      this.handleContent(content, ContentTypes.TEXT);\n    }\n  }\n}\n"],"names":[],"mappings":"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"}