npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qapm/sse-monitor

v1.1.4

Published

qapm js sse monitor client

Downloads

17

Readme

RUM大模型体验分析web-sdk使用文档

sdk版本:1.1.4

1、接入参数说明

| 字段名 | 是否必填 | 类型 | 说明 | 默认值 | | ----------------------- | -------- | ------------- | ------------------------------------------------------------------------------ | ----------------------- | | ​app_key​ | 是 | string | 上报的ID,需在RUM产品创建并获取,https://console.cloud.tencent.com/monitor/app | | | ​llm_ver​ | 是 | string | 大模型版本号,可通过 setLLMVer 动态设置 | | | ​include_url_reg​ | 是 | array | 需要监控的URL正则表达式数组 | | | ​use_fetch​ | 否 | boolean | 是否监控 window.fetch 的流式请求 | true | | ​use_xhr​ | 否 | boolean | 是否监控 window.XMLHttpRequest 的流式请求 | true | | ​user_event_source​ | 否 | boolean | 是否监控 window.EventSource | true | | ​user_id​ | 否 | string | 用户ID,可通过 setUserID 动态设置 | | | ​qapm_base_url​ | 否 | string | 性能数据上报地址 | https://app.rumt-zh.com | | ​version​ | 否 | string | 前端版本号 | | | ​host_ip​ | 否 | string | 接口服务端IP,可通过 setHostIP 动态设置 | UNSUPPORTED | | ​log_level​ | 否 | string (枚举) | 日志级别:none(关闭)、error、warn、info、debug、log | none | | ​onMessage​ | 否 | function | 每次收到消息后的回调函数 | null | | ​onAfterRequest​ | 否 | function | sse请求结束后的回调函数 | null |

2、接入方式

(1)使用script标签的方式接入

    <script src="https://qapmcdn-1253358381.cos.ap-guangzhou.myqcloud.com/web-sdk/latest/sse.qapm.js"></script>
    <script>
        const option = {
            app_key: "5f68970f-10248",
            llm_ver: "deepseek-7b",
            include_url_reg: [/conversation/, /https\:\/\/fibona\.woa\.com\/v1\/component\/session\/\d+$/],

            use_fetch: true,
            use_xhr: true,
            use_event_source: true,
            user_id: "smithabc",
            qapm_base_url: "https://app.rumt-zh.com",
            version: "1.0.0",
            host_ip: "10.2.3.40"
        }
        window.QAPM.initLLMMonitor(option)
    </script>

(2)npm安装后,使用import接入

安装依赖:

npm install @qapm/sse-monitor

引入:

import {
    initLLMMonitor
} from "@qapm/sse-monitor"
const option = {
    app_key: "5f68970f-10248",
    llm_ver: "deepseek-7b",
    include_url_reg: [/conversation/, /https\:\/\/fibona\.woa\.com\/v1\/component\/session\/\d+$/],

    use_fetch: true,
    use_xhr: true,
    use_event_source: true,
    user_id: "smithabc",
    qapm_base_url: "https://app.rumt-zh.com",
    version: "1.0.0",
    host_ip: "10.2.3.40"
}
initLLMMonitor(option)

3、可用接口

(1)设置用户ID

import {
    setUserID
} from "@qapm/sse-monitor";
setUserID("OA::smithdeng");
或者
window.QAPM.setUserID("OA::smithdeng");

(2)设置模型版本

import {
    setLLMVer
} from "@qapm/sse-monitor";
setLLMVer("hunyuan-7b");
或者
window.QAPM.setLLMVer("hunyuan-7b");

(3)设置模型接口的服务端IP

import {
    setHostIP
} from "@qapm/sse-monitor";
setHostIP("10.2.3.40");
或者
window.QAPM.setHostIP("10.2.3.40");

(4)自定义上报

使用此接口可以自定义上报数据, sseEvent的数据结构请参考 数据结构 章节。

import {
    perfEvent
} from "@qapm/sse-monitor";
const sseEvent = {
    category: "PERF_NET_SSE",
    tags: {
        d1: "https://fibona.woa.com/v1/component/session/1234567890",
        d2: "fibona.woa.com",
        d3: "deepseek-7b",
        d4: "false",
        d5: "false",
        d12: "10.2.3.40",
        d15: "true",
        d16: "true",
        d20: "user_id::smithabc",
        d21: "talk_id::1234567890",
        d22: "ask_content::你好",
        d23: "answer_content::你好",
    },
    values: {
        v1: 1,
        v2: 1,
        v3: 0,
        v4: 0,
        v5: 0,
        v6: 0,
        v7: 1
    }
}
perfEvent(sseEvent, true);
或者
window.QAPM.perfEvent(sseEvent, true);

4、回调函数

(1)每次收到消息后的回调函数,onMessage

在初始化adk的时候,可以传递一个onMessage的回调函数,该回调函数会在每次收到消息后被调用,参数如下: | 参数名 | 类型 | 说明 | | ---------------- | -------- | ------------------- | | ​cookie​ | string | 返回document.cookie | | ​reqHeader​ | Object | 请求的header | | ​reqBody​ | Object | 请求的body | | ​respHeader​ | Object | 响应的header | | ​respBody​ | Object | 响应的body | | ​message​ | string | 每次收到的消息 | | ​sseOption​ | Object | 初始化sdk的参数 | | ​sseEvent​ | SSEEvent | 采集的sse性能数据 |

注意:onMessage必须要返回sseEvent。

import {
    initLLMMonitor
} from "@qapm/sse-monitor"
const option = {
    app_key: "5f68970f-10248",
    llm_ver: "deepseek-7b",
    include_url_reg: [/conversation/, /https\:\/\/fibona\.woa\.com\/v1\/component\/session\/\d+$/],

    use_fetch: true,
    use_xhr: true,
    use_event_source: true,
    user_id: "smithabc",
    qapm_base_url: "https://app.rumt-zh.com",
    version: "1.0.0",
    host_ip: "10.2.3.40",
    onMessage: (cookie, reqHeader, reqBody, respHeader, respBody, message, sseOption, sseEvent) => {
        const now = Date.now();
        try {
            console.log('onMessage', message)

            // 开放自定义日志上下文字段,v20-v29
            if (message.includes("start") && !sseEvent.values.v20) {
                sseEvent.values.v20 = now; // 首包时间戳
            }

            if (message.includes("think_start") && !sseEvent.values.v21) {
                sseEvent.values.v21 = now; // 开启深度思考,思考的开始时间戳
            }

            if (message.includes("think_end") && !sseEvent.values.v22) {
                sseEvent.values.v22 = now; // 开启深度思考,思考的结束时间戳
            }

            if (message.includes("content_start") && !sseEvent.values.v23) {
                sseEvent.values.v23 = now; // 正文的开始时间戳
            }

            if (message.includes("content_end") && !sseEvent.values.v24) {
                sseEvent.values.v24 = now; // 正文的结束时间戳
            }

        } catch (e) {
            console.log('onMessage error', e)
        }

        return sseEvent;
    }
}
initLLMMonitor(option)

(2)sse请求结束后的回调函数,onAfterRequest

在初始化adk的时候,可以传递一个onAfterRequest的回调函数,该回调函数会在每次请求结束后被调用,参数如下:

| 参数名 | 类型 | 说明 | | ---------------- | -------- | ------------------- | | ​cookie​ | string | 返回document.cookie | | ​reqHeader​ | Object | 请求的header | | ​reqBody​ | Object | 请求的body | | ​respHeader​ | Object | 响应的header | | ​respBody​ | Object | 响应的body | | ​sseOption​ | Object | 初始化sdk的参数 | | ​sseEvent​ | SSEEvent | 采集的sse性能数据 |

onAfterRequest必须要有返回值,如果在onAfterRequest中返回了sseEvent,则会覆盖原有的sseEvent,如果返回了false,则不会上报该sseEvent。

其中sseEvent为用户暴露如下字段: | 参数名 | 类型 | 说明 | | ---------------------------- | ------ | ---------- | | ​sseEvent.tags.d15-d19​ | string | 指标聚合 | | ​sseEvent.tags.d20-d29​ | string | 日志上下文 | | ​sseEvent.values.v1-v29​ | number | 日志上下文 |

import {
    initLLMMonitor
} from "@qapm/sse-monitor"
const option = {
    app_key: "5f68970f-10248",
    llm_ver: "deepseek-7b",
    include_url_reg: [/conversation/, /https\:\/\/fibona\.woa\.com\/v1\/component\/session\/\d+$/],

    use_fetch: true,
    use_xhr: true,
    use_event_source: true,
    user_id: "smithabc",
    qapm_base_url: "https://app.rumt-zh.com",
    version: "1.0.0",
    host_ip: "10.2.3.40",
    onAfterRequest: (cookie, reqHeader, reqBody, respHeader, respBody, sseOption, sseEvent) => {
        try {
            console.log('onAfterRequest', cookie, reqHeader, reqBody, respHeader, respBody, sseOption, sseEvent)

            const reqJson = reqBody;

            // 开放自定义指标聚合字段,d15-d19 
            sseEvent.tags.d15 = reqJson.openDeepThink || "false"; // 是否开启了深度思考
            sseEvent.tags.d16 = reqJson.openWebSearch || "false"; // 是否开启了联网搜索

            // 开放自定义日志上下文字段,d20-d29
            sseEvent.tags.d20 = "talk_id::" + reqJson.talkId || ""; // 对话ID
            sseEvent.tags.d21 = "ask_content::" + reqJson.askContent || ""; // 对话的问题
            sseEvent.tags.d22 = "answer_content::" + respBody || ""; // 回复的正文内容

            // 上报到灯塔
            // uploadToLightHouse(sseEvent);

        } catch (e) {
            console.log('onAfterRequest error', e)
        }

        return sseEvent;
    }
}
initLLMMonitor(option)

5、数据结构

(1)sseEvent的数据结构

  interface SSEEvent {
      /** 事件分类(固定为性能监控类) */
      category: "PERF_NET_SSE";
      tags: {
          /** 请求 URL */
          d1: string;
          /** 请求 HOST */
          d2: string;
          /** 模型版本 */
          d3: string;
          /** 是否错误 */
          d4: "true" | "false";
          /** 是否卡死 */
          d5: "true" | "false";
          /** 主机 IP(不支持时显示 UNSUPPORTED) */
          d12: string | "UNSUPPORTED";

          /** 开放字段d15-d19,用于指标聚合*/
          d15 ?: string;
          d16 ?: string;
          d17 ?: string;
          d18 ?: string;
          d19 ?: string;

          /** 开放字段d20-d29,用于日志上下文展示*/
          d20 ?: string;
          d21 ?: string;
          d22 ?: string;
          d23 ?: string;
          d24 ?: string;
          d25 ?: string;
          d26 ?: string;
          d27 ?: string;
          d28 ?: string;
          d29 ?: string;
      };
      values: {
          /** 总token数 */
          v1: number;
          /** 消息耗时分段统计 */
          v2: number; // [0,500)ms 的消息数量
          v3: number; // [500,1000)ms 的消息数量
          v4: number; // [1000,3000)ms 的消息数量
          v5: number; // [3000,10000)ms 的消息数量
          v6: number; // [10000,60000)ms 的消息数量

          /** 耗时累计统计 */
          v7: number; // 连接打开时间戳
          v8: number; // 首条消息时间戳
          v9: number; // 最后消息时间戳
          v10: number; // 接收到response header 的时间戳,仅xhr支持

          /** 耗时累计统计 */
          v12: number; // [0,500)ms 总耗时
          v13: number; // [500,1000)ms 总耗时
          v14: number; // [1000,3000)ms 总耗时
          v15: number; // [3000,10000)ms 总耗时
          v16: number; // [10000,60000)ms 总耗时

          /** 数据传输量 */
          v17: number; // 请求数据总量(字节)
          v18: number; // 响应数据总量(字节)

          /** 开放字段v20-v29,用于日志上下文展示*/
          v20 ?: number;
          v21 ?: number;
          v22 ?: number;
          v23 ?: number;
          v24 ?: number;
          v25 ?: number;
          v26 ?: number;
          v27 ?: number;
          v28 ?: number;
          v29 ?: number;

          /** 消息耗时分段统计 */
          v30 : number; // [60000ms,+∞)ms 的消息数量

          /** 耗时累计统计 */
          v31 : number; // [60000ms,+∞)ms 总耗时

      };
  }

(2)初始化sdk的参数的数据结构

  interface LLMMonitorOptions {
      app_key: string;
      llm_ver: string;
      include_url_reg ? : RegExp[];
      use_fetch ? : boolean;
      use_xhr ? : boolean;
      use_event_source ? : boolean;
      user_id ? : string;
      qapm_base_url ? : string;
      version ? : string;
      host_ip ? : string;
      log_level ? : string;
      onMessage ? : (
          cookie: string,
          reqHeader: Object,
          reqBody: Object,
          respHeader: Object,
          respBody: Object,
          message: string,
          sseOption: LLMMonitorOptions,
          sseEvent: SSEEvent
      ) => Object;
      onAfterRequest ? : (
          cookie: string,
          reqHeader: Object,
          reqBody: Object,
          respHeader: Object,
          respBody: Object,
          sseOption: LLMMonitorOptions,
          sseEvent: SSEEvent
      ) => Object;
  }