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

@roll-agent/octopus-agent

v0.3.1

Published

Octopus Agent:编排 Sponge MCP Server 的 NL2SQL 查询链路

Readme

Octopus Agent

Octopus Agent 是 Node.js 实现的轻量 NL2SQL(自然语言转 SQL)调用客户端。正常查询调用 query_sponge(查询 Sponge),SQL 修复由 Sponge 主流程内部完成;查询成功后根据 Sponge 返回的能力契约,可继续调用 analyze_query_result(分析查询结果)或 export_query_csv(导出全部数据)。丸子不负责图表生成。

询问能力、没有可识别的查询对象或查询动作、闲聊、无关问题或要求增删改业务数据时,由 LLM(大语言模型)调用 get_query_guidance(获取查询引导);程序不使用字符串或正则匹配用户原话。查询引导只是动态示例,不是能力白名单;明确业务查询即使重复提出、未出现在引导中或仅缺少筛选条件具体值,也必须调用 query,由 Sponge 判断是否追问。用户要求使用、启动或检查丸子 Agent 时,仅通过 GET /mcp/health 执行健康检查,不尝试简单业务查询。

上一轮 query 返回 clarifying(等待补充条件)或成功结果展示『猜你想查』后,用户选择编号或追加其他要求时,下一次 query.question(查询问题)仍逐字传入用户本轮原话,例如 2,并分析;禁止在 Octopus 中替换为选项正文,选项解析和历史继承由 Sponge 统一处理。

本地运行

要求 Node.js 22.6 或更高版本。query 使用 @roll-agent/sdkdefineTool(定义工具)和 Zod(输入校验)声明入参;现有 MCP 响应适配层继续负责标准答案和结构化内容。

npm install
npm test
npm start

Roll Agent 接入

roll agent add .
roll run octopus-agent query --json \
  --input-json '{"question":"查询本月各门店销售额","isNewConversation":true}'

上层平台必须明确传递 isNewConversation(是否新对话)。当前上层对话第一次调用丸子 Agent 时传 true;后续调用传 false。后续调用可以回传上一次结果中的 structuredContent.contextId,实现精确续接;没有回传时,Agent 会从该访问令牌最近 5 个上下文中进行语义选择。

query(自然语言查询)入参:

| 字段 | 必填 | 中文说明 | |-|-|-| | question | 是 | 用户原始问题,不得改写 | | isNewConversation | 是 | 是否为当前上层对话第一次调用丸子 Agent;新对话传 true,后续传 false | | contextId | 否 | 上一次返回的上下文 ID;isNewConversation=false 时用于精确续接 | | resultFormat | 否 | 结果格式,支持 text/json/yaml/md/markdown/html,默认 markdown(Markdown 格式) |

同一上层对话的后续调用示例:

roll run octopus-agent query --json \
  --input-json '{"question":"其中肯德基有多少个岗位","isNewConversation":false,"contextId":"ctx_a1b2"}'

isNewConversation=true 时禁止同时传入 contextId,避免新对话误接旧上下文。

上层模型调用时使用 --json(完整 JSON),只读取 content[0].text(最终文本)及 structuredContent.contextId(结构化内容中的上下文 ID)等必要字段。

export_query_csv(导出全部数据)接收必填的 queryId(查询编号)和可选的 analysisRequest(分析要求)。仅当上一条结果的 structuredContent.availableActions(可用动作)包含 export_query_csv 时,用户追问“导出 CSV”“导出全部”“把刚才结果导出”等纯导出诉求才直接沿用该查询编号。同一上层对话存在多次成功查询时,新查询覆盖此前的默认续接目标;用户未明确指定更早对象或查询编号时,只能使用时间上最后一次成功 query 返回的 queryId。用户要求“导出并分析”时只调用本工具,将本轮原话逐字传入 analysisRequest,禁止随后调用只分析页面快照的 analyze_query_result;只要求导出时省略。不再次调用 query,也不改写上一条问题。Sponge MCP Server 基于实际导出的最多 1000 条数据生成分析,并将同一份分析统一写入 answer(答案)和 CSV,octopus-agent 原样展示,不自行生成或补充分析。用户同时修改筛选条件时才发起新的 query

纯图表要求不属于丸子能力,由独立 Chart Agent(图表智能体)处理。用户同时要求查询和生成图表时,Roll 先通过 Octopus 完成查询并导出 CSV,再将 CSV 临时地址和用户原始制图要求交给 Chart Agent;Octopus 不识别图型、不生成 HTML,也不为制图重新查询。

analyze_query_result(分析查询结果)接收必填的 queryIdanalysisRequest(分析要求)。仅当上一条结果的 availableActions 包含 analyze_query_result,且用户只要求分析、没有同时要求导出时调用;查询当轮待分析时沿用 Sponge 返回的分析要求,用户后续追问分析时逐字传入本轮要求,不重新查询。

get_query_guidance(获取查询引导)接收必填的 showQueryOnlyNotice(是否展示仅支持查询提示)和可选的 role(角色),角色支持 operation(运营)、personal(个人)和 supplier(供应商)。能力询问传 false;闲聊、无关问题、没有可识别的查询对象或查询动作、增删改请求传 true。仅缺少筛选条件具体值时调用 query。Tool 返回 Sponge 内存快照中的本周热门、推荐问题、标准示例和可选筛选条件。

query 的结构化结果包含 resultKind(结果类型)、availableActionspendingActions(待执行动作)及可能存在的 exportResult(自动导出结果)。pendingActions 非空时 terminal=false(当前调用链未结束),上层按顺序调用对应工具;全部完成后再统一展示每次工具返回的 content[0].textresultKind=report(报表)且动作列表为空时,不显示查询编号,也不允许套用普通查询的导出或分析动作。

health(健康检查)无入参,返回 Sponge MCP Server 及业务库、权限库、审计库的 UP(正常)或 DOWN(异常)状态。

环境变量

| 环境变量 | 必填 | 中文说明 | 默认值 | |-|-|-|-| | SPONGE_MCP_BASE_URL | 是 | Sponge MCP Server 地址 | https://sponge-mcp.duliday.com | | SPONGE_MCP_ACCESS_TOKEN | 是 | 身份透传 Token(令牌) | 无 |

Agent 内置单次请求超时 58 秒、query(查询)总超时 59 秒、网络重试 2 次,无需额外配置。每个新问题生成新的 requestId(请求编号),仅网络重试复用该编号。总超时低于当前 Roll 的 60 秒固定限制。

最终答案的“此次查询耗时”使用 Agent 记录的 agentDurationSeconds(Agent 总耗时),计算范围为 octopus-agent 收到 query 请求到生成可交给平台渲染的 content[0].text,包含上下文处理、网络传输、服务端处理和答案组装,精确到 3 位小数。MCP Server 不再计算或返回总耗时;平台收到 Tool 结果后的 UI(用户界面)绘制耗时不在 Agent 可观测范围内。

isNewConversation=true 时 octopus-agent 直接生成全局唯一 contextId(上下文 ID),不读取历史。isNewConversation=false 且传入 contextId 时精确续接;未传入时从 MCP Server 获取当前访问令牌最近 5 个上下文及每个上下文最近 5 轮问答,再由 Roll Core LLM(大语言模型)选择 continue(继续上下文)或 new(新话题)。多个候选同样合理时保守新建,避免并行聊天串线。MCP Server 在生成 SQL 时根据最终 ID 独立加载最近 5 轮;禁止 Server 自行切换 ID。requestId(请求编号)仍由 octopus-agent 每次请求重新生成。

Sponge Server 返回的 steps(阶段数据)仅用于内部审计,不再透传给上层 Agent;完整步骤通过现有 PostgreSQL 审计记录查看。

查询成功后,octopus-agent 直接使用 Sponge MCP Server 返回的 answer(答案),不校验是否包含数据分析,不调用 Roll Core Sampling(采样调用),也不使用程序重新生成分析。普通可续接查询追加 Agent 查询耗时和查询编号;报表等无后续动作结果不追加查询编号。最终内容放在 result.content[0].textresult.content[1] 只要求上层 Agent 逐字复制并在需要时继续执行 pendingActions,不要求外层模型分析或重建表格。查询返回的 resultAnalysis(结果分析信息)和 steps(阶段数据)不再透传;contextIdcontextAction(上下文动作)和 contextReason(判断原因)保留在 result.structuredContent(结构化内容)中。

接口名称:export_query_csv(导出全部数据)

接口说明:重新校验并执行原查询 SQL,最多导出 1000 条;传入 analysisRequest 时基于实际导出数据生成分析,并把同一份分析写入页面答案和 CSV。

入参:

| 字段 | 必填 | 中文说明 | |-|-|-| | queryId | 是 | 原查询编号,必须来自上一条可导出的查询结果 | | analysisRequest | 否 | 用户本轮逐字提出的分析要求;只导出时省略 |

回参:

| 字段 | 中文说明 | |-|-| | queryId | 原查询编号 | | rowCount | 实际导出条数 | | url | CSV 下载地址 | | expiresAt | 下载地址过期时间 | | answer | 下载信息,以及按需生成的完整导出数据分析 | | resultAnalysis | 按需返回的分析文本、状态和导出统计摘要 |

curl -X POST 'http://localhost:3001/mcp/tools/export_query_csv' \
  -H 'Authorization: Bearer <访问令牌>' \
  -H 'Content-Type: application/json' \
  -d '{"queryId":"qry_a1b2","analysisRequest":"分析多次上岗人员和门店分布"}'
{
  "queryId": "qry_a1b2",
  "rowCount": 1000,
  "url": "http://localhost:3001/mcp/exports/example",
  "expiresAt": "2026-08-26T10:00:00.000Z",
  "answer": "## 导出结果\n已生成 CSV,共 1000 条。\n\n## 数据分析\n以下结论基于本次实际导出的 1000 条数据。",
  "resultAnalysis": {
    "status": "llm",
    "text": "以下结论基于本次实际导出的 1000 条数据。",
    "summary": {
      "rowCount": 1000,
      "exportLimit": 1000,
      "exportLimitReached": true
    }
  }
}

MCP Server 内部接口

接口名称:get_query_guidance(获取查询引导)

接口说明:读取 Sponge 已聚合的内存快照,可按角色筛选推荐内容。

入参:

| 字段 | 必填 | 中文说明 | |-|-|-| | role | 否 | 角色:operation(运营)、personal(个人)、supplier(供应商) |

回参:

| 字段 | 中文说明 | |-|-| | snapshot | 快照时间范围、生成时间及下次刷新时间 | | weeklyHotQuestions | 本周热门问题 | | recommendedQuestions | 推荐问题 | | blueprintGroups | 可复用查询蓝图分组 |

curl -X POST 'http://localhost:3001/mcp/tools/get_query_guidance' \
  -H 'Authorization: Bearer <访问令牌>' \
  -H 'Content-Type: application/json' \
  -d '{"role":"supplier"}'
{
  "snapshot": {
    "timezone": "Asia/Shanghai",
    "weekStart": "2026-08-24T00:00:00+08:00",
    "weekEndExclusive": "2026-08-31T00:00:00+08:00",
    "generatedAt": "2026-08-25T09:00:00+08:00",
    "nextRefreshAt": "2026-08-25T12:30:00+08:00"
  },
  "weeklyHotQuestions": [],
  "recommendedQuestions": [],
  "blueprintGroups": []
}

接口名称:analyze_query_result(分析查询结果)

接口说明:基于已成功查询的服务端留存结果执行专项分析,不重新生成或执行 SQL。

入参:

| 字段 | 必填 | 中文说明 | |-|-|-| | queryId | 是 | 原查询编号,必须来自上一条结果 | | analysisRequest | 否 | 分析要求;不传时复用原查询已保存的明确要求,但最终必须存在非空要求 |

回参:

| 字段 | 中文说明 | |-|-| | queryId | 原查询编号 | | status | 分析状态 | | analysisRequest | 本次分析要求 | | answer | 已渲染的分析正文 | | analysis | 分析内容 | | analysisStatus | 模型分析状态 | | cached | 是否复用已有分析 |

curl -X POST 'http://localhost:3001/mcp/tools/analyze_query_result' \
  -H 'Authorization: Bearer <访问令牌>' \
  -H 'Content-Type: application/json' \
  -d '{"queryId":"qry_a1b2","analysisRequest":"比较供应商高低"}'
{
  "queryId": "qry_a1b2",
  "status": "succeeded",
  "analysisRequest": "比较供应商高低",
  "answer": "## 数据分析\n甲供应商高于乙供应商。",
  "analysis": "甲供应商高于乙供应商。",
  "analysisStatus": "llm",
  "cached": false
}

接口名称:get_context_candidates(获取候选上下文)

接口说明:根据鉴权访问令牌返回最近 5 个成功上下文,每个上下文包含最近 5 轮成功问答。无业务入参,访问令牌 ID 由 MCP Server 鉴权获得。

返回字段:

| 字段 | 中文说明 | |-|-| | candidates | 候选上下文数组,最多 5 个 | | candidates[].contextId | 上下文 ID | | candidates[].lastActiveAt | 上下文最后成功查询时间 | | candidates[].history | 最近成功问答数组,最多 5 条 | | history[].question | 用户原始问题 | | history[].answer | 对应查询答案 |

curl -X POST 'http://localhost:3001/mcp/tools/get_context_candidates' \
  -H 'Authorization: Bearer <访问令牌>' \
  -H 'Content-Type: application/json' \
  -d '{}'
{
  "candidates": [
    {
      "contextId": "ctx_a1b2",
      "lastActiveAt": "2026-07-17T10:00:00.000Z",
      "history": [
        { "question": "上海有多少品牌", "answer": "上海共有 391 个品牌" }
      ]
    }
  ]
}

安全边界

  • 正常查询只调用一次 query_sponge;SQL 生成、校验和最多两次自动修复都由 Sponge 主流程完成。
  • 上一条查询的 availableActions 包含 export_query_csv 时,纯导出追问才沿用 queryId 调用该工具;禁止重新调用 query_sponge。导出仍由 Sponge MCP Server 去掉展示上限、应用导出上限并重新执行安全与权限校验。
  • 上一条查询的 availableActions 包含 analyze_query_result 时,才可沿用 queryId 做专项分析;查询当轮待分析时沿用服务端要求,后续追问时逐字传入用户本轮要求,禁止自行改写或重跑查询。
  • 查询已自动导出全部数据时,保留 Sponge 返回的 exportResult,直接展示下载与分析正文。
  • 导出成功时,Sponge MCP Server 返回的 answer 已包含 CSV 下载信息和完整导出数据分析;octopus-agent 与上层 Agent 只能原样展示。
  • 查询返回 failed(失败)时原样展示服务端错误并结束,禁止追问或自行补充查询条件。
  • 查询返回 clarifying(等待补充条件)时原样展示服务端追问;用户下一轮补充条件后使用原 contextId 继续调用 query
  • 查询成功或失败都使用 renderMode=verbatim_markdown(原样 Markdown)或 renderMode=verbatim(原样文本)。octopus-agent 不校验或补充 Sponge MCP Server 返回的 answer;上层 Agent 只能逐字展示 content[0].textterminal=false 时按 pendingActions 顺序继续调用,不重新查询;terminal=truenextAction=stop 时结束调用链。
  • 使用或检查 Agent 时只调用 health,禁止通过 query 做连接测试。
  • 非明确查询场景调用 get_query_guidance;能力询问直接展示动态引导,其他场景先说明目前只支持查询。
  • 未经用户明确确认,不调用 export_query_csv
  • Agent 不接收或传入任意 SQL。
  • Agent 不读取 Schema,不生成 SQL,也不生成数据分析;Roll Core LLM 仅用于上下文语义判断,不使用正则或硬编码业务判断。
  • 认证 Token 仅用于身份透传,数据权限由 Sponge MCP Server 校验。
  • 不新建数据库。MCP Server 使用现有 mcp_query_run 持久化完整问答,并按访问令牌提供最近 5 个上下文。上下文恢复不依赖 Agent 进程内存。