@guandata/guanbi-mcp-server 0.1.17 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
| `BI_PUBLIC_PATH` | 否 | 空字符串 | BI 部署在子路径时填写,例如 `/guanbi`。 |
|
|
34
34
|
| `BI_REQUEST_TIMEOUT_MS` | 否 | `120000` | BI 请求超时时间,单位毫秒。 |
|
|
35
35
|
| `BI_MAX_ROWS` | 否 | `1000` | `execute_sql_query` 返回行数上限,会作为 `limit` 参数传给 BI 接口;实际限制以 BI 接口能力为准。 |
|
|
36
|
-
| `BI_DATA_VERSION` | 否 | - | 手工覆盖能力判断使用的 BI 版本,例如 `8.2.
|
|
36
|
+
| `BI_DATA_VERSION` | 否 | - | 手工覆盖能力判断使用的 BI 版本,例如 `8.2.0`。 |
|
|
37
37
|
| `GUANBI_MCP_USAGE_STATS` | 否 | 开启 | 匿名聚合使用统计开关;设置为 `0`、`false`、`off` 或 `no` 可关闭。 |
|
|
38
38
|
| `MCP_TRANSPORT` | 否 | `stdio` | 运行模式;传 `streamable-http` 启用企业 HTTP 模式。 |
|
|
39
39
|
|
|
@@ -99,6 +99,15 @@ X-GuanBI-Login-Id: <loginId>
|
|
|
99
99
|
<BI_USER_PROPERTY_HEADER>: <external user id>
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
Aily / 飞书接入默认可以用 `x-aily-user` 映射 BI 用户属性 `feishu`。如果飞书 user id(Aily 中询问得到的用户 id)和飞书管理后台「成员与部门」->「成员详情」->「用户ID」中看到的用户 ID 不同,可以改用邮箱匹配:
|
|
103
|
+
|
|
104
|
+
```env
|
|
105
|
+
BI_USER_PROPERTY_HEADER=x-aily-email
|
|
106
|
+
BI_USER_PROPERTY_KEY=email
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
邮箱匹配要求飞书里每个用户都配置了邮箱,且邮箱已同步到 BI 用户属性 `email` 中,并能唯一匹配一个 BI 用户。
|
|
110
|
+
|
|
102
111
|
`X-GuanBI-Login-Id`、`BI_USER_PROPERTY_HEADER` 配置的用户属性 header 等身份 header 是普通 HTTP header,必须只来自可信调用方或网关确认后的身份映射。可信网关模式下,网关必须覆盖注入身份 header,不能透传外部请求自带的同名 header。
|
|
103
112
|
|
|
104
113
|
## Tools
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"dotenv/config";import{z as E}from"zod";var fr=E.object({BI_BASE_URL:E.string().url().optional(),BI_PUBLIC_PATH:E.string().optional().default(""),BI_UID_TOKEN:E.string().optional(),BI_LOGIN_DOMAIN:E.string().optional().default("guanbi"),BI_LOGIN_ID:E.string().optional(),BI_LOGIN_PASSWORD:E.string().optional(),BI_APP_TOKEN:E.string().optional(),BI_LOGIN_ID_HEADER:E.string().optional(),BI_USER_PROPERTY_HEADER:E.string().optional(),BI_USER_PROPERTY_KEY:E.string().optional(),BI_IDENTITY_DEBUG:E.string().optional(),BI_IDENTITY_TOKEN_CACHE_TTL_MS:E.coerce.number().int().positive().default(6e5),BI_REQUEST_TIMEOUT_MS:E.coerce.number().int().positive().default(12e4),BI_MAX_ROWS:E.coerce.number().int().positive().default(1e3),BI_DATA_VERSION:E.string().optional(),GUANBI_MCP_USAGE_STATS:E.string().optional(),MCP_TRANSPORT:E.enum(["stdio","streamable-http"]).optional().default("stdio"),MCP_HTTP_HOST:E.string().optional().default("127.0.0.1"),MCP_HTTP_PORT:E.coerce.number().int().nonnegative().optional().default(9090),MCP_ENTRYPOINT_TOKEN:E.string().optional(),MCP_TRUSTED_GATEWAY:E.string().optional()});function mt(e=process.env){let t=fr.parse(e);return{...t,BI_BASE_URL:t.BI_BASE_URL?.replace(/\/+$/,""),BI_PUBLIC_PATH:gr(t.BI_PUBLIC_PATH),BI_UID_TOKEN:t.BI_UID_TOKEN?.trim()||void 0,BI_LOGIN_DOMAIN:t.BI_LOGIN_DOMAIN?.trim()||"guanbi",BI_LOGIN_ID:t.BI_LOGIN_ID?.trim()||void 0,BI_LOGIN_PASSWORD:t.BI_LOGIN_PASSWORD?.trim()||void 0,BI_APP_TOKEN:t.BI_APP_TOKEN?.trim()||void 0,BI_LOGIN_ID_HEADER:t.BI_LOGIN_ID_HEADER===void 0?"x-guanbi-login-id":pt(t.BI_LOGIN_ID_HEADER),BI_USER_PROPERTY_HEADER:pt(t.BI_USER_PROPERTY_HEADER),BI_USER_PROPERTY_KEY:t.BI_USER_PROPERTY_KEY?.trim()||void 0,BI_IDENTITY_DEBUG:t.BI_IDENTITY_DEBUG?.trim()||void 0,BI_DATA_VERSION:t.BI_DATA_VERSION?.trim()||void 0,GUANBI_MCP_USAGE_STATS:t.GUANBI_MCP_USAGE_STATS?.trim()||void 0,MCP_ENTRYPOINT_TOKEN:t.MCP_ENTRYPOINT_TOKEN?.trim()||void 0,MCP_TRUSTED_GATEWAY:t.MCP_TRUSTED_GATEWAY?.trim()||void 0}}function gr(e){let t=e?.trim().replace(/^\/+|\/+$/g,"")??"";return t?`/${t}`:""}function pt(e){return e?.trim().toLowerCase()||void 0}import{createRequire as ro}from"module";import{createHash as io,randomUUID as so}from"crypto";import{createServer as oo}from"http";import{McpServer as ao}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as uo}from"@modelcontextprotocol/sdk/server/stdio.js";import{StreamableHTTPServerTransport as co}from"@modelcontextprotocol/sdk/server/streamableHttp.js";var oe=class{record(t){console.error(JSON.stringify({audit:_r({...t})}))}},ae=class{record(){}};function Re(e,t,n,r,i){return{transport:t.transport,tool:e,tenantId:t.audit.tenantId,endUserId:t.audit.endUserId,traceId:t.audit.traceId,status:r,durationMs:Math.max(0,Date.now()-n),failureType:r==="error"?hr(i):void 0}}function hr(e){return e instanceof Error?e.name||"Error":typeof e}function _r(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}import{AsyncLocalStorage as Ir}from"async_hooks";var ue={client:"X-Guandata-Client",clientVersion:"X-Guandata-Client-Version",command:"X-Guandata-Command"},ft=new Ir;function gt(e,t){return ft.run(e,t)}function X(e){e=ft.getStore()??e;let t={},n=e?.client.trim();n&&(t[ue.client]=n);let r=e?.clientVersion?.trim();r&&(t[ue.clientVersion]=r);let i=e?.command?.trim();return i&&(t[ue.command]=i),t}function G(e,t){let n=X(t);if(!Object.keys(n).length)return e;let r=new Set(Object.values(ue).map(i=>i.toLowerCase()));return{...Object.fromEntries(Object.entries(e).filter(([i])=>!r.has(i.toLowerCase()))),...n}}async function ce(e){if(!e.BI_LOGIN_ID||!e.BI_LOGIN_PASSWORD||!e.BI_LOGIN_DOMAIN)throw new Error("\u5BC6\u7801\u767B\u5F55\u9700\u8981\u914D\u7F6E BI_LOGIN_DOMAIN\u3001BI_LOGIN_ID\u3001BI_LOGIN_PASSWORD\u3002");let t=await fetch(br(e,"/api/user/sign-in"),{method:"POST",headers:{"Content-Type":"application/json","raw-backend-response":"TRUE",...X(e.BI_REQUEST_METADATA)},body:JSON.stringify({domain:e.BI_LOGIN_DOMAIN,loginId:e.BI_LOGIN_ID,password:Buffer.from(e.BI_LOGIN_PASSWORD,"utf8").toString("base64")}),signal:AbortSignal.timeout(e.BI_REQUEST_TIMEOUT_MS)}),n=await t.text();if(!t.ok)throw new Error(`BI \u767B\u5F55\u5931\u8D25\uFF1AHTTP ${t.status} ${Sr(n)}`);let r=yr(t,n);if(!r)throw new Error("BI \u767B\u5F55\u54CD\u5E94\u4E2D\u672A\u627E\u5230 X-Auth-Token/Authorization/uIdToken/authToken/token\u3002");return{token:r}}function br(e,t){return`${e.BI_BASE_URL}${e.BI_PUBLIC_PATH}${t}`}function yr(e,t){let n=Tr(e.headers);if(n)return n;let r=Cr(t);return r||Er(e.headers)}function Tr(e){let t=e.get("x-auth-token")?.trim();if(t)return t;let n=e.get("authorization")?.trim();return n&&(n.match(/^Bearer\s+(.+)$/i)?.[1]??n).trim()||void 0}function Cr(e){try{let t=JSON.parse(e);return ht(t)??ht(Br(t.response))}catch{return}}function Er(e){return[...e.getSetCookie?.()??[],...wr(e.get("set-cookie"))].map(n=>n.trim().match(/(?:^|;\s*)uIdToken=([^;]+)/)?.[1]).find(Boolean)}function wr(e){return e?e.split(/,(?=\s*[^;,]+=)/):[]}function ht(e){if(e)for(let t of["uIdToken","authToken","token"]){let n=e[t];if(typeof n=="string"&&n)return n}}function Br(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function Sr(e,t=500){return e.length>t?`${e.slice(0,t)}...`:e}var Rr="guanbi_mcp_chatbi",O=class extends Error{detail;retryableForBaseUrl;authExpired;constructor(t,n,r={}){super(t),this.name="ChatBIRequestError",this.detail=n,this.retryableForBaseUrl=!!r.retryableForBaseUrl,this.authExpired=!!r.authExpired}},v=class{constructor(t){this.config=t;this.token=t.BI_UID_TOKEN,this.candidates=t.BI_BASE_URL?Or(`${t.BI_BASE_URL}${t.BI_PUBLIC_PATH}`):[]}config;token;resolvedBaseUrl;candidates;triedBaseUrls=new Set;lastError;loginPromise;refreshPromise;getRegisteredTools(){return["chatbi_list_themes","chatbi_query","chatbi_insight_start","chatbi_insight_poll"]}getResolvedBaseUrl(){return this.resolvedBaseUrl}getTriedBaseUrls(){return[...this.triedBaseUrls]}getLastError(){return this.lastError}async probe(){try{return await this.listThemes(),{available:!0,resolvedBaseUrl:this.resolvedBaseUrl,triedBaseUrls:this.getTriedBaseUrls(),registeredTools:this.getRegisteredTools()}}catch(t){let n=_t(t,"probe");return{available:!1,lastError:n,failureType:Jr(n),triedBaseUrls:this.getTriedBaseUrls(),registeredTools:this.getRegisteredTools()}}}async listThemes(t={}){let n={filter_enable:!0,list_type:"CHAT"};return typeof t.isInsight=="boolean"&&(n.is_insight=t.isInsight),(await this.request("/theme/list-theme",{operation:"listThemes",body:n,retrySafeBaseUrlFallback:!0,validateResponse:qr})).themes}async query(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!1),r={attachments:[],theme_id:n,message:t.message,config:It({fast_mode:t.fastMode??!0,n_samples:t.nSamples})};t.sessionId&&(r.session_id=t.sessionId),t.externalContext&&(r.external_context=t.externalContext);let i=await this.request("/chat/send-message-sync",{operation:"query",body:r,includeDeviceId:!0});try{Fr(i)}catch(s){throw this.operationError("query","/chat/send-message-sync",s)}return i}async insight(t){let n=t.timeoutMs??3e5,r=t.pollIntervalMs??2e3,i=Date.now()+n,s=await this.startInsight({...t,requestTimeoutMs:bt(i)});if(!s.theme_id)throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing theme_id");if(!s.message_id?.trim())throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing message_id");for(;;){let o=await this.getAgentAnswer(s.theme_id,s.message_id,bt(i));switch(o.message_id??=s.message_id,o.session_id??=s.session_id,o.status){case"success":return o;case"failure":case"stopped":throw this.operationError("insight.poll","/chat/get-agent-answer",o.detail?.trim()||"Insight request failed")}await Qr(i,r,n)}}async startInsight(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!0),r={attachments:[],theme_id:n,message:t.message,is_insight:1};t.sessionId&&(r.session_id=t.sessionId),t.externalContext&&(r.external_context=t.externalContext);let i=It({analysis_expert_id:t.analysisExpertId,agent_mode:t.agentMode,analysis_confirmation_enabled:t.analysisConfirmationEnabled});Object.keys(i).length&&(r.config=i);let s=await this.request("/chat/send-message",{operation:"insight.send",body:r,includeDeviceId:!0,requestTimeoutMs:t.requestTimeoutMs});if(!s.message_id?.trim())throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing message_id");return s.theme_id=n,s}async pollInsight(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!0),r=await this.getAgentAnswer(n,t.messageId,t.requestTimeoutMs);return r.message_id||(r.message_id=t.messageId),r}async getAgentAnswer(t,n,r){let i=new URLSearchParams({theme_id:t,message_id:n});try{return await this.request(`/chat/get-agent-answer?${i.toString()}`,{operation:"insight.poll",retrySafeBaseUrlFallback:!0,requestTimeoutMs:r})}catch(s){if(jr(s))return{status:"waiting",message_id:n};throw s}}async resolveThemeId(t,n,r){let i=t?.trim();if(i)return i;let s=n?.trim();if(!s)throw new Error("\u7F3A\u5C11\u4E3B\u9898\u9009\u62E9\uFF0C\u8BF7\u4F20 theme_id \u6216 theme_name\u3002");let o=await this.listThemes({isInsight:r?!0:void 0});return $r(o,s)}async request(t,n){this.assertUsableConfig();let r=this.resolvedBaseUrl?[this.resolvedBaseUrl]:this.candidates,i;for(let s of r){this.triedBaseUrls.add(s);try{let o=await this.requestToBaseUrlWithAuthRetry(s,t,n);return n.validateResponse?.(o,{operation:n.operation,baseUrl:s,path:t}),this.resolvedBaseUrl=s,this.lastError=void 0,o}catch(o){if(i=o,this.lastError=_t(o,n.operation),!xr(o,n.retrySafeBaseUrlFallback))throw this.withTriedBaseUrls(o)}}throw this.withTriedBaseUrls(i??new Error("\u65E0\u6CD5\u5B9A\u4F4D ChatBI Public API\u3002"))}withTriedBaseUrls(t){return t instanceof O&&(t.detail.tried_base_urls=this.getTriedBaseUrls(),this.lastError=t.detail),t}operationError(t,n,r){let i=r instanceof Error?r.message:String(r);return new O(i,{operation:t,base_url:this.resolvedBaseUrl,path:n,chatbi_message:i,tried_base_urls:this.getTriedBaseUrls(),detail:i})}async requestToBaseUrlWithAuthRetry(t,n,r){let i=await this.ensureToken(),s={operation:r.operation,baseUrl:t,path:n};try{return await this.requestToBaseUrl(t,n,i,r,s)}catch(o){if(!Mr(o)||!this.canRefreshToken())throw o;let a=await this.refreshToken();return this.requestToBaseUrl(t,n,a,r,{...s,tokenRefreshed:!0})}}async requestToBaseUrl(t,n,r,i,s){let o=i.body===void 0?"GET":"POST",a;try{a=await fetch(`${t}${n}`,{method:o,headers:Ar(r,i,this.config.BI_REQUEST_METADATA),body:i.body===void 0?void 0:JSON.stringify(i.body),signal:AbortSignal.timeout(i.requestTimeoutMs??this.config.BI_REQUEST_TIMEOUT_MS)})}catch(d){throw new O(d instanceof Error?d.message:String(d),{operation:s.operation,base_url:s.baseUrl,path:s.path,token_refreshed:s.tokenRefreshed,detail:d instanceof Error?d.message:String(d)})}let u=await a.text(),c=kr(u,a,s);if(!a.ok||Pr(c))throw vr(c,u,a,s);return this.refreshTokenFromResponse(a,c),c.data}async ensureToken(){return this.token?this.token:(this.loginPromise??=this.signInForToken().finally(()=>{this.loginPromise=void 0}),this.loginPromise)}async refreshToken(){return this.refreshPromise??=this.refreshTokenOnce().finally(()=>{this.refreshPromise=void 0}),this.refreshPromise}async refreshTokenOnce(){if(this.config.BI_UID_TOKEN_REFRESH){let t=await this.config.BI_UID_TOKEN_REFRESH();return this.token=t,t}return this.signInForToken()}async signInForToken(){this.token=void 0;let t=await ce(this.config);return this.token=t.token,t.token}refreshTokenFromResponse(t,n){let r=Gr(t,n);!r||r===this.token||(this.token=r)}hasPasswordLogin(){return!!(this.config.BI_LOGIN_DOMAIN&&this.config.BI_LOGIN_ID&&this.config.BI_LOGIN_PASSWORD)}canRefreshToken(){return!!this.config.BI_UID_TOKEN_REFRESH||this.hasPasswordLogin()}assertUsableConfig(){if(!this.config.BI_BASE_URL)throw new Error("\u7F3A\u5C11 BI_BASE_URL\uFF0C\u65E0\u6CD5\u63A8\u5BFC ChatBI Public API \u5730\u5740\u3002")}};function Or(e){let t=new URL(e),n=[],r=s=>{let o=new URL(t.toString());o.pathname=s,o.search="",o.hash="";let a=o.toString().replace(/\/+$/,"");n.includes(a)||n.push(a)},i=t.pathname.replace(/\/+$/,"");return r("/api/chat/public-api"),i&&r(`${i}/api/chat/public-api`),r(i?`${i}/public-api`:"/public-api"),r("/public-api"),n}function de(e){return e.BI_BASE_URL?e.BI_UID_TOKEN?!0:!!(e.BI_LOGIN_DOMAIN&&e.BI_LOGIN_ID&&e.BI_LOGIN_PASSWORD):!1}function Ar(e,t,n){let r={Cookie:`uIdToken=${e}`,"User-Agent":"guanbi-mcp-server",...X(n)};return t.body!==void 0&&(r["Content-Type"]="application/json"),t.includeDeviceId&&(r["Device-ID"]=Rr),r}function kr(e,t,n){if(!e)return{};try{return JSON.parse(e)}catch{throw new O("ChatBI response is not valid JSON",{operation:n.operation,base_url:n.baseUrl,path:n.path,http_status:t.status,token_refreshed:n.tokenRefreshed,detail:Ct(e)},{retryableForBaseUrl:!0})}}function Pr(e){let t=yt(e);return typeof t=="number"&&![0,200].includes(t)||e.result==="fail"||e.success===!1}function vr(e,t,n,r){let i=yt(e),s=Nr(e),o=s||t||`ChatBI request failed with status ${n.status}`,a={operation:r.operation,base_url:r.baseUrl,path:r.path,http_status:n.status,chatbi_code:i,chatbi_message:s,token_refreshed:r.tokenRefreshed,detail:Ct(t)},u=Lr(o),c=!u&&Dr(n.status,i);return new O(o,a,{authExpired:c,retryableForBaseUrl:u||Ur(n.status,i)})}function xr(e,t){return!!(t&&e instanceof O&&e.retryableForBaseUrl)}function Mr(e){return e instanceof O&&e.authExpired}function Dr(e,t){return e===401||e===403||t===401||t===403||t===5001}function Ur(e,t){return[401,403,404,405].includes(e)||typeof t=="number"&&[401,403,404,405].includes(t)}function jr(e){return e instanceof O&&e.detail.http_status===200&&e.detail.chatbi_code===404&&e.detail.chatbi_message==="Message not found."}function yt(e){if(typeof e.code=="number")return e.code;let t=le(e.error);return typeof t?.status=="number"?t.status:void 0}function Nr(e){if(typeof e.message=="string"&&e.message.trim())return e.message;let t=le(e.error);return typeof t?.message=="string"&&t.message.trim()?t.message:void 0}function Lr(e){return/No static resource/i.test(e)}function le(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function qr(e,t){let n=le(e);if(!Array.isArray(n?.themes))throw new O("ChatBI list-theme response missing themes",{operation:t.operation,base_url:t.baseUrl,path:t.path,detail:"missing themes"},{retryableForBaseUrl:!0})}function Gr(e,t){let r=[...e.headers.getSetCookie?.()??[],...Hr(e.headers.get("set-cookie"))].map(s=>Oe(s.trim().match(/(?:^|;\s*)uIdToken=([^;]+)/)?.[1])).find(Boolean);if(r)return r;let i=Oe(e.headers.get("x-auth-token"));return i||Tt(t)}function Hr(e){return e?e.split(/,(?=\s*[^;,]+=)/):[]}function Oe(e){if(typeof e!="string")return;let t=e.trim();return t&&!/\s/.test(t)?t:void 0}function Tt(e){let t=le(e);if(t){for(let n of["uIdToken","authToken"]){let r=Oe(t[n]);if(r)return r}for(let n of["data","response"]){let r=Tt(t[n]);if(r)return r}}}function _t(e,t){return e instanceof O?e.detail:{operation:t,detail:e instanceof Error?e.message:String(e)}}function Ct(e,t=1e3){return e.length>t?`${e.slice(0,t)}...`:e}function Jr(e){let t=`${e.chatbi_message??""} ${e.detail??""}`;return/BI 登录失败|密码登录|sign-?in|login/i.test(t)?"login_failed":e.http_status===401||e.http_status===403||e.chatbi_code===401||e.chatbi_code===403?"permission_denied":/No static resource|not valid JSON/i.test(t)||e.http_status===404||e.http_status===405||e.chatbi_code===404||e.chatbi_code===405?"public_api_unreachable":"unknown"}function $r(e,t){let n=t.trim().toLowerCase(),r,i=[];for(let s of e){let o=s.theme_name.trim().toLowerCase();o===n?r=s:o.includes(n)&&i.push(s)}if(r)return r.theme_id;if(i.length===1)return i[0].theme_id;throw i.length>1?new Error(`\u4E3B\u9898\u540D\u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF1A${t}`):new Error(`\u672A\u627E\u5230\u4E3B\u9898\uFF1A${t}`)}function It(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>typeof t<"u"))}function Fr(e){if([e.final_status,e.answer_status,e.query_status].some(zr))throw new Error(`ChatBI query failed: ${Vr(e.query_context?.err_msg,e.query_context?.detail,e.query_context?.msg,e.answer_context?.detail,e.answer_context?.msg,"unknown failure")}`);if(!e.answer?.explain?.trim()&&!(e.query_result?.columns?.length||e.query_result?.preview?.length))throw new Error("ChatBI response missing query content")}function Vr(...e){return e.find(t=>typeof t=="string"&&t.trim())?.trim()}function zr(e){return typeof e=="string"&&e.trim().toLowerCase()==="failure"}function bt(e){let t=e-Date.now();if(t<=0)throw new Error("Insight request timed out");return t}async function Qr(e,t,n){let r=e-Date.now();if(r<=0)throw new Error(`Insight request timed out after ${n}ms`);await new Promise(i=>setTimeout(i,Math.min(t,r)))}var Z="8.2.1",ke=["search_metrics","list_metric_catalog","get_metric_detail","query_metric_data","search_metric_trees","get_metric_tree_detail","query_metric_tree_attribution"],Kr=["get_bi_capabilities","global_search",...ke,"execute_sql_query","get_dataset_detail","get_card_info","query_card_data","get_page_info"],Yr=6e4,Ae=new WeakMap;async function te(e,t){let n=Ae.get(e);return(!n||n.expiresAt<=Date.now())&&Ae.set(e,{expiresAt:Date.now()+Yr,promise:Xr(e,t).catch(r=>Wr(r,t))}),Ae.get(e).promise}function Bt(e){let t=!e.BI_BASE_URL,n="HTTP \u6A21\u5F0F\u4E0B execute_sql_query \u4F1A\u5728\u8C03\u7528\u65F6\u4F7F\u7528\u5F53\u524D\u7528\u6237 token \u5224\u65AD BI \u7248\u672C/\u80FD\u529B\u3002",r="HTTP \u6A21\u5F0F\u542F\u52A8\u671F\u5C1A\u672A\u89E3\u6790\u8BF7\u6C42\u8C03\u7528\u8005\u3002";return{ok:!t,error:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":void 0,versionSource:"api",dataVersion:e.BI_DATA_VERSION,service:ve(e,t?["get_bi_capabilities"]:Pe(e)),caller:{ok:!1,error:r,features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:r}},chatbi:ee(e,r)},features:{executeSqlQuery:{enabled:!t,minVersion:Z,reason:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":n}},metricPlatform:{registeredTools:t?[]:ke,readOnly:!0,lastError:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":void 0},chatbi:ee(e,"HTTP \u6A21\u5F0F\u542F\u52A8\u671F\u4E0D\u4F7F\u7528\u67D0\u4E2A\u7528\u6237 token \u63A2\u6D4B ChatBI \u80FD\u529B\u3002")}}async function St(e,t,n){let i=(await te(e,t)).features[n];if(!i.enabled)throw new Error(`\u5F53\u524D BI \u73AF\u5883\u4E0D\u652F\u6301 ${n}\uFF1A${i.reason??"\u80FD\u529B\u672A\u542F\u7528"}`)}function Wr(e,t){let n=e instanceof Error?e.message:String(e);return{ok:!1,error:n,versionSource:"api",features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:`\u65E0\u6CD5\u786E\u8BA4 BI \u80FD\u529B\uFF1A${n}`}},metricPlatform:{registeredTools:[],readOnly:!0,lastError:n},chatbi:ee(t,n),service:ve(t,Pe(t)),caller:{ok:!1,error:n,features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:`\u65E0\u6CD5\u786E\u8BA4 BI \u80FD\u529B\uFF1A${n}`}},chatbi:ee(t,n)}}}async function Xr(e,t){let n=ei(t);if(n.length)throw new Error(`\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A${n.join("\uFF1B")}\u3002`);let r=t.BI_DATA_VERSION?"env":"api",i=t.BI_DATA_VERSION?{dataVersion:t.BI_DATA_VERSION,capabilityVersion:t.BI_DATA_VERSION}:await ti(e),s=ni(i.capabilityVersion,Z),o=await Zr(t);return{ok:!0,appVersion:i.appVersion,dataVersion:i.dataVersion,versionSource:r,service:ve(t,Pe(t)),caller:{ok:!0,features:{executeSqlQuery:s},chatbi:o},features:{executeSqlQuery:s},metricPlatform:{registeredTools:ke,readOnly:!0},chatbi:o}}function Pe(e){let t=new Set(Kr);if(de(e)||e.MCP_TRANSPORT==="streamable-http")for(let n of new v(e).getRegisteredTools())t.add(n);return[...t]}function ve(e,t){return{mode:e.MCP_TRANSPORT??"stdio",toolList:t,boundBISite:{configured:!!e.BI_BASE_URL,baseUrl:e.BI_BASE_URL,publicPath:e.BI_PUBLIC_PATH}}}async function Zr(e){let t=new v(e);return de(e)?t.probe():ee(e,"\u7F3A\u5C11 BI_BASE_URL \u6216\u9274\u6743\u914D\u7F6E\u3002")}function ee(e,t){return{available:!1,registeredTools:de(e)?new v(e).getRegisteredTools():[],failureType:"unknown",triedBaseUrls:[],lastError:{operation:"probe",chatbi_message:t,detail:t}}}function ei(e){let t=[];if(e.BI_BASE_URL||t.push("\u7F3A\u5C11 BI_BASE_URL"),!e.BI_UID_TOKEN){let n=[["BI_LOGIN_DOMAIN",e.BI_LOGIN_DOMAIN],["BI_LOGIN_ID",e.BI_LOGIN_ID],["BI_LOGIN_PASSWORD",e.BI_LOGIN_PASSWORD]].filter(([,r])=>!r).map(([r])=>r);n.length&&t.push(`\u7F3A\u5C11\u9274\u6743\u914D\u7F6E\uFF1A\u8BF7\u914D\u7F6E BI_UID_TOKEN\uFF0C\u6216\u8865\u5168\u8D26\u53F7\u5BC6\u7801\u767B\u5F55\u914D\u7F6E\uFF08\u7F3A\u5C11 ${n.join("\u3001")}\uFF09`)}return t}async function ti(e){let t=await e.get("/api/server-version"),n=wt(t.version),r=wt(t.dataVersion)??n;if(!r)throw new Error("BI \u7248\u672C\u63A5\u53E3\u672A\u8FD4\u56DE version \u6216 dataVersion\u3002");return{appVersion:n,dataVersion:r,capabilityVersion:r}}function ni(e,t){let n=Et(e),r=Et(t);if(!r)throw new Error(`\u5185\u90E8\u914D\u7F6E\u9519\u8BEF\uFF1A\u65E0\u6CD5\u89E3\u6790\u6700\u4F4E\u7248\u672C ${t}\u3002`);if(!n)return{enabled:!1,minVersion:t,reason:`\u65E0\u6CD5\u4ECE\u7248\u672C\u5B57\u7B26\u4E32 "${e}" \u4E2D\u89E3\u6790\u4EA7\u54C1\u7248\u672C\uFF0C\u8BF7\u914D\u7F6E BI_DATA_VERSION\u3002`};let i=ri(n,r)>=0;return{enabled:i,minVersion:t,reason:i?void 0:`\u9700\u8981 BI ${t}+\uFF0C\u5F53\u524D\u7248\u672C\u4E3A ${e}\u3002`}}function Et(e){let t=e.match(/(\d+)\.(\d+)\.(\d+)/);if(t)return[Number(t[1]),Number(t[2]),Number(t[3])]}function ri(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function wt(e){return typeof e=="string"&&e.trim()?e.trim():void 0}var pe=class{constructor(t){this.config=t}config;cache=new Map;async exchange(t){let n=Rt(t),r=this.cache.get(this.cacheKey(n));if(r&&r.expiresAtMs>Date.now())return this.result(n,r.token,r.biExpireAt);let i=await this.fetchLoginIdToken(n);return this.cache.set(this.cacheKey(n),{token:i.token,expiresAtMs:this.resolveCacheExpiresAt(i.expireAt),biExpireAt:i.expireAt}),this.result(n,i.token,i.expireAt)}async exchangeUserProperty(t){let n=await this.fetchLoginIdByUserProperty(t);return this.exchange(n)}async refresh(t){return this.cache.delete(this.cacheKey(t)),(await this.exchange(t)).token}result(t,n,r){return{token:n,expireAt:r,refresh:()=>this.refresh(t)}}async fetchLoginIdByUserProperty(t){let n=ii(t);if(!this.config.BI_BASE_URL)throw this.debugError("BI_BASE_URL is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});if(!this.config.BI_APP_TOKEN)throw this.debugError("BI_APP_TOKEN is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});let r=this.config.BI_USER_PROPERTY_KEY?.trim();if(!r)throw this.debugError("BI_USER_PROPERTY_KEY is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});let i=this.buildUrl("/public-api/user/properties/list"),s={token:this.config.BI_APP_TOKEN,userPropertyKey:r,userPropertyValue:n,enabled:!0,offset:0,limit:2},o;try{o=await fetch(i,{method:"POST",headers:G({"Content-Type":"application/json","raw-backend-response":"TRUE"},this.config.BI_REQUEST_METADATA),body:JSON.stringify(s),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}catch(p){throw this.debugError(`BI user property lookup request failed: ${p instanceof Error?p.message:String(p)}`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},error:p instanceof Error?p.message:String(p)},[this.config.BI_APP_TOKEN])}let a=await o.text(),u=Ot(a);if(!o.ok||At(u))throw this.debugError(`BI user property lookup failed: HTTP ${o.status} ${xe(a,[this.config.BI_APP_TOKEN,r,n])}`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},response:{status:o.status,body:a}},[this.config.BI_APP_TOKEN]);let c=u?.response?.list??[],d=u?.response?.total??c.length;if(d!==1||c.length!==1)throw this.debugError(`BI user property lookup must match exactly one user: matched ${d} user(s) for ${r}.`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},response:{status:o.status,total:d,listCount:c.length,matchedLoginIds:c.map(p=>p.loginId).filter(Boolean)}},[this.config.BI_APP_TOKEN]);return Rt(c[0]?.loginId??"")}async fetchLoginIdToken(t){if(!this.config.BI_BASE_URL)throw this.debugError("BI_BASE_URL is required for loginId identity exchange.",{operation:"loginIdSignIn",request:{loginId:t}});if(!this.config.BI_APP_TOKEN)throw this.debugError("BI_APP_TOKEN is required for loginId identity exchange.",{operation:"loginIdSignIn",request:{loginId:t}});let n=this.buildUrl("/public-api/user/loginId/sign-in"),r={token:this.config.BI_APP_TOKEN,loginId:t},i;try{i=await fetch(n,{method:"POST",headers:G({"Content-Type":"application/json","raw-backend-response":"TRUE"},this.config.BI_REQUEST_METADATA),body:JSON.stringify(r),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}catch(u){throw this.debugError(`BI loginId token exchange request failed: ${u instanceof Error?u.message:String(u)}`,{operation:"loginIdSignIn",request:{method:"POST",url:n,body:r},error:u instanceof Error?u.message:String(u)},[this.config.BI_APP_TOKEN])}let s=await i.text(),o=Ot(s),a=o?.response?.token?.trim();if(!i.ok||At(o)||!a)throw this.debugError(`BI loginId token exchange failed: HTTP ${i.status} ${xe(s,[this.config.BI_APP_TOKEN,a,t])}`,{operation:"loginIdSignIn",request:{method:"POST",url:n,body:r},response:{status:i.status,body:s}},[this.config.BI_APP_TOKEN,a]);return{token:a,expireAt:o?.response?.expireAt}}buildUrl(t){let n=t.startsWith("/")?t:`/${t}`;return`${this.config.BI_BASE_URL}${this.config.BI_PUBLIC_PATH}${n}`}cacheKey(t){return`${this.config.BI_BASE_URL??""}${this.config.BI_PUBLIC_PATH}\0${t}`}resolveCacheExpiresAt(t){let n=Date.now()+this.config.BI_IDENTITY_TOKEN_CACHE_TTL_MS,r=si(t);return r?Math.min(n,r):n}debugError(t,n,r=[]){if(!ai(this.config))return new Error(t);let i=Me(n,[this.config.BI_APP_TOKEN,...r]);return console.error(JSON.stringify({identityExchangeDebug:i})),new Error(`${t}
|
|
2
|
+
import"dotenv/config";import{z as E}from"zod";var fr=E.object({BI_BASE_URL:E.string().url().optional(),BI_PUBLIC_PATH:E.string().optional().default(""),BI_UID_TOKEN:E.string().optional(),BI_LOGIN_DOMAIN:E.string().optional().default("guanbi"),BI_LOGIN_ID:E.string().optional(),BI_LOGIN_PASSWORD:E.string().optional(),BI_APP_TOKEN:E.string().optional(),BI_LOGIN_ID_HEADER:E.string().optional(),BI_USER_PROPERTY_HEADER:E.string().optional(),BI_USER_PROPERTY_KEY:E.string().optional(),BI_IDENTITY_DEBUG:E.string().optional(),BI_IDENTITY_TOKEN_CACHE_TTL_MS:E.coerce.number().int().positive().default(6e5),BI_REQUEST_TIMEOUT_MS:E.coerce.number().int().positive().default(12e4),BI_MAX_ROWS:E.coerce.number().int().positive().default(1e3),BI_DATA_VERSION:E.string().optional(),GUANBI_MCP_USAGE_STATS:E.string().optional(),MCP_TRANSPORT:E.enum(["stdio","streamable-http"]).optional().default("stdio"),MCP_HTTP_HOST:E.string().optional().default("127.0.0.1"),MCP_HTTP_PORT:E.coerce.number().int().nonnegative().optional().default(9090),MCP_ENTRYPOINT_TOKEN:E.string().optional(),MCP_TRUSTED_GATEWAY:E.string().optional()});function mt(e=process.env){let t=fr.parse(e);return{...t,BI_BASE_URL:t.BI_BASE_URL?.replace(/\/+$/,""),BI_PUBLIC_PATH:gr(t.BI_PUBLIC_PATH),BI_UID_TOKEN:t.BI_UID_TOKEN?.trim()||void 0,BI_LOGIN_DOMAIN:t.BI_LOGIN_DOMAIN?.trim()||"guanbi",BI_LOGIN_ID:t.BI_LOGIN_ID?.trim()||void 0,BI_LOGIN_PASSWORD:t.BI_LOGIN_PASSWORD?.trim()||void 0,BI_APP_TOKEN:t.BI_APP_TOKEN?.trim()||void 0,BI_LOGIN_ID_HEADER:t.BI_LOGIN_ID_HEADER===void 0?"x-guanbi-login-id":pt(t.BI_LOGIN_ID_HEADER),BI_USER_PROPERTY_HEADER:pt(t.BI_USER_PROPERTY_HEADER),BI_USER_PROPERTY_KEY:t.BI_USER_PROPERTY_KEY?.trim()||void 0,BI_IDENTITY_DEBUG:t.BI_IDENTITY_DEBUG?.trim()||void 0,BI_DATA_VERSION:t.BI_DATA_VERSION?.trim()||void 0,GUANBI_MCP_USAGE_STATS:t.GUANBI_MCP_USAGE_STATS?.trim()||void 0,MCP_ENTRYPOINT_TOKEN:t.MCP_ENTRYPOINT_TOKEN?.trim()||void 0,MCP_TRUSTED_GATEWAY:t.MCP_TRUSTED_GATEWAY?.trim()||void 0}}function gr(e){let t=e?.trim().replace(/^\/+|\/+$/g,"")??"";return t?`/${t}`:""}function pt(e){return e?.trim().toLowerCase()||void 0}import{createRequire as ro}from"module";import{createHash as io,randomUUID as so}from"crypto";import{createServer as oo}from"http";import{McpServer as ao}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as uo}from"@modelcontextprotocol/sdk/server/stdio.js";import{StreamableHTTPServerTransport as co}from"@modelcontextprotocol/sdk/server/streamableHttp.js";var oe=class{record(t){console.error(JSON.stringify({audit:_r({...t})}))}},ae=class{record(){}};function Re(e,t,n,r,i){return{transport:t.transport,tool:e,tenantId:t.audit.tenantId,endUserId:t.audit.endUserId,traceId:t.audit.traceId,status:r,durationMs:Math.max(0,Date.now()-n),failureType:r==="error"?hr(i):void 0}}function hr(e){return e instanceof Error?e.name||"Error":typeof e}function _r(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}import{AsyncLocalStorage as Ir}from"async_hooks";var ue={client:"X-Guandata-Client",clientVersion:"X-Guandata-Client-Version",command:"X-Guandata-Command"},ft=new Ir;function gt(e,t){return ft.run(e,t)}function X(e){e=ft.getStore()??e;let t={},n=e?.client.trim();n&&(t[ue.client]=n);let r=e?.clientVersion?.trim();r&&(t[ue.clientVersion]=r);let i=e?.command?.trim();return i&&(t[ue.command]=i),t}function G(e,t){let n=X(t);if(!Object.keys(n).length)return e;let r=new Set(Object.values(ue).map(i=>i.toLowerCase()));return{...Object.fromEntries(Object.entries(e).filter(([i])=>!r.has(i.toLowerCase()))),...n}}async function ce(e){if(!e.BI_LOGIN_ID||!e.BI_LOGIN_PASSWORD||!e.BI_LOGIN_DOMAIN)throw new Error("\u5BC6\u7801\u767B\u5F55\u9700\u8981\u914D\u7F6E BI_LOGIN_DOMAIN\u3001BI_LOGIN_ID\u3001BI_LOGIN_PASSWORD\u3002");let t=await fetch(br(e,"/api/user/sign-in"),{method:"POST",headers:{"Content-Type":"application/json","raw-backend-response":"TRUE",...X(e.BI_REQUEST_METADATA)},body:JSON.stringify({domain:e.BI_LOGIN_DOMAIN,loginId:e.BI_LOGIN_ID,password:Buffer.from(e.BI_LOGIN_PASSWORD,"utf8").toString("base64")}),signal:AbortSignal.timeout(e.BI_REQUEST_TIMEOUT_MS)}),n=await t.text();if(!t.ok)throw new Error(`BI \u767B\u5F55\u5931\u8D25\uFF1AHTTP ${t.status} ${Sr(n)}`);let r=yr(t,n);if(!r)throw new Error("BI \u767B\u5F55\u54CD\u5E94\u4E2D\u672A\u627E\u5230 X-Auth-Token/Authorization/uIdToken/authToken/token\u3002");return{token:r}}function br(e,t){return`${e.BI_BASE_URL}${e.BI_PUBLIC_PATH}${t}`}function yr(e,t){let n=Tr(e.headers);if(n)return n;let r=Cr(t);return r||Er(e.headers)}function Tr(e){let t=e.get("x-auth-token")?.trim();if(t)return t;let n=e.get("authorization")?.trim();return n&&(n.match(/^Bearer\s+(.+)$/i)?.[1]??n).trim()||void 0}function Cr(e){try{let t=JSON.parse(e);return ht(t)??ht(Br(t.response))}catch{return}}function Er(e){return[...e.getSetCookie?.()??[],...wr(e.get("set-cookie"))].map(n=>n.trim().match(/(?:^|;\s*)uIdToken=([^;]+)/)?.[1]).find(Boolean)}function wr(e){return e?e.split(/,(?=\s*[^;,]+=)/):[]}function ht(e){if(e)for(let t of["uIdToken","authToken","token"]){let n=e[t];if(typeof n=="string"&&n)return n}}function Br(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function Sr(e,t=500){return e.length>t?`${e.slice(0,t)}...`:e}var Rr="guanbi_mcp_chatbi",O=class extends Error{detail;retryableForBaseUrl;authExpired;constructor(t,n,r={}){super(t),this.name="ChatBIRequestError",this.detail=n,this.retryableForBaseUrl=!!r.retryableForBaseUrl,this.authExpired=!!r.authExpired}},v=class{constructor(t){this.config=t;this.token=t.BI_UID_TOKEN,this.candidates=t.BI_BASE_URL?Or(`${t.BI_BASE_URL}${t.BI_PUBLIC_PATH}`):[]}config;token;resolvedBaseUrl;candidates;triedBaseUrls=new Set;lastError;loginPromise;refreshPromise;getRegisteredTools(){return["chatbi_list_themes","chatbi_query","chatbi_insight_start","chatbi_insight_poll"]}getResolvedBaseUrl(){return this.resolvedBaseUrl}getTriedBaseUrls(){return[...this.triedBaseUrls]}getLastError(){return this.lastError}async probe(){try{return await this.listThemes(),{available:!0,resolvedBaseUrl:this.resolvedBaseUrl,triedBaseUrls:this.getTriedBaseUrls(),registeredTools:this.getRegisteredTools()}}catch(t){let n=_t(t,"probe");return{available:!1,lastError:n,failureType:Jr(n),triedBaseUrls:this.getTriedBaseUrls(),registeredTools:this.getRegisteredTools()}}}async listThemes(t={}){let n={filter_enable:!0,list_type:"CHAT"};return typeof t.isInsight=="boolean"&&(n.is_insight=t.isInsight),(await this.request("/theme/list-theme",{operation:"listThemes",body:n,retrySafeBaseUrlFallback:!0,validateResponse:qr})).themes}async query(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!1),r={attachments:[],theme_id:n,message:t.message,config:It({fast_mode:t.fastMode??!0,n_samples:t.nSamples})};t.sessionId&&(r.session_id=t.sessionId),t.externalContext&&(r.external_context=t.externalContext);let i=await this.request("/chat/send-message-sync",{operation:"query",body:r,includeDeviceId:!0});try{Fr(i)}catch(s){throw this.operationError("query","/chat/send-message-sync",s)}return i}async insight(t){let n=t.timeoutMs??3e5,r=t.pollIntervalMs??2e3,i=Date.now()+n,s=await this.startInsight({...t,requestTimeoutMs:bt(i)});if(!s.theme_id)throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing theme_id");if(!s.message_id?.trim())throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing message_id");for(;;){let o=await this.getAgentAnswer(s.theme_id,s.message_id,bt(i));switch(o.message_id??=s.message_id,o.session_id??=s.session_id,o.status){case"success":return o;case"failure":case"stopped":throw this.operationError("insight.poll","/chat/get-agent-answer",o.detail?.trim()||"Insight request failed")}await Qr(i,r,n)}}async startInsight(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!0),r={attachments:[],theme_id:n,message:t.message,is_insight:1};t.sessionId&&(r.session_id=t.sessionId),t.externalContext&&(r.external_context=t.externalContext);let i=It({analysis_expert_id:t.analysisExpertId,agent_mode:t.agentMode,analysis_confirmation_enabled:t.analysisConfirmationEnabled});Object.keys(i).length&&(r.config=i);let s=await this.request("/chat/send-message",{operation:"insight.send",body:r,includeDeviceId:!0,requestTimeoutMs:t.requestTimeoutMs});if(!s.message_id?.trim())throw this.operationError("insight.send","/chat/send-message","ChatBI insight response missing message_id");return s.theme_id=n,s}async pollInsight(t){let n=await this.resolveThemeId(t.themeId,t.themeName,!0),r=await this.getAgentAnswer(n,t.messageId,t.requestTimeoutMs);return r.message_id||(r.message_id=t.messageId),r}async getAgentAnswer(t,n,r){let i=new URLSearchParams({theme_id:t,message_id:n});try{return await this.request(`/chat/get-agent-answer?${i.toString()}`,{operation:"insight.poll",retrySafeBaseUrlFallback:!0,requestTimeoutMs:r})}catch(s){if(jr(s))return{status:"waiting",message_id:n};throw s}}async resolveThemeId(t,n,r){let i=t?.trim();if(i)return i;let s=n?.trim();if(!s)throw new Error("\u7F3A\u5C11\u4E3B\u9898\u9009\u62E9\uFF0C\u8BF7\u4F20 theme_id \u6216 theme_name\u3002");let o=await this.listThemes({isInsight:r?!0:void 0});return $r(o,s)}async request(t,n){this.assertUsableConfig();let r=this.resolvedBaseUrl?[this.resolvedBaseUrl]:this.candidates,i;for(let s of r){this.triedBaseUrls.add(s);try{let o=await this.requestToBaseUrlWithAuthRetry(s,t,n);return n.validateResponse?.(o,{operation:n.operation,baseUrl:s,path:t}),this.resolvedBaseUrl=s,this.lastError=void 0,o}catch(o){if(i=o,this.lastError=_t(o,n.operation),!xr(o,n.retrySafeBaseUrlFallback))throw this.withTriedBaseUrls(o)}}throw this.withTriedBaseUrls(i??new Error("\u65E0\u6CD5\u5B9A\u4F4D ChatBI Public API\u3002"))}withTriedBaseUrls(t){return t instanceof O&&(t.detail.tried_base_urls=this.getTriedBaseUrls(),this.lastError=t.detail),t}operationError(t,n,r){let i=r instanceof Error?r.message:String(r);return new O(i,{operation:t,base_url:this.resolvedBaseUrl,path:n,chatbi_message:i,tried_base_urls:this.getTriedBaseUrls(),detail:i})}async requestToBaseUrlWithAuthRetry(t,n,r){let i=await this.ensureToken(),s={operation:r.operation,baseUrl:t,path:n};try{return await this.requestToBaseUrl(t,n,i,r,s)}catch(o){if(!Mr(o)||!this.canRefreshToken())throw o;let a=await this.refreshToken();return this.requestToBaseUrl(t,n,a,r,{...s,tokenRefreshed:!0})}}async requestToBaseUrl(t,n,r,i,s){let o=i.body===void 0?"GET":"POST",a;try{a=await fetch(`${t}${n}`,{method:o,headers:Ar(r,i,this.config.BI_REQUEST_METADATA),body:i.body===void 0?void 0:JSON.stringify(i.body),signal:AbortSignal.timeout(i.requestTimeoutMs??this.config.BI_REQUEST_TIMEOUT_MS)})}catch(d){throw new O(d instanceof Error?d.message:String(d),{operation:s.operation,base_url:s.baseUrl,path:s.path,token_refreshed:s.tokenRefreshed,detail:d instanceof Error?d.message:String(d)})}let u=await a.text(),c=kr(u,a,s);if(!a.ok||Pr(c))throw vr(c,u,a,s);return this.refreshTokenFromResponse(a,c),c.data}async ensureToken(){return this.token?this.token:(this.loginPromise??=this.signInForToken().finally(()=>{this.loginPromise=void 0}),this.loginPromise)}async refreshToken(){return this.refreshPromise??=this.refreshTokenOnce().finally(()=>{this.refreshPromise=void 0}),this.refreshPromise}async refreshTokenOnce(){if(this.config.BI_UID_TOKEN_REFRESH){let t=await this.config.BI_UID_TOKEN_REFRESH();return this.token=t,t}return this.signInForToken()}async signInForToken(){this.token=void 0;let t=await ce(this.config);return this.token=t.token,t.token}refreshTokenFromResponse(t,n){let r=Gr(t,n);!r||r===this.token||(this.token=r)}hasPasswordLogin(){return!!(this.config.BI_LOGIN_DOMAIN&&this.config.BI_LOGIN_ID&&this.config.BI_LOGIN_PASSWORD)}canRefreshToken(){return!!this.config.BI_UID_TOKEN_REFRESH||this.hasPasswordLogin()}assertUsableConfig(){if(!this.config.BI_BASE_URL)throw new Error("\u7F3A\u5C11 BI_BASE_URL\uFF0C\u65E0\u6CD5\u63A8\u5BFC ChatBI Public API \u5730\u5740\u3002")}};function Or(e){let t=new URL(e),n=[],r=s=>{let o=new URL(t.toString());o.pathname=s,o.search="",o.hash="";let a=o.toString().replace(/\/+$/,"");n.includes(a)||n.push(a)},i=t.pathname.replace(/\/+$/,"");return r("/api/chat/public-api"),i&&r(`${i}/api/chat/public-api`),r(i?`${i}/public-api`:"/public-api"),r("/public-api"),n}function de(e){return e.BI_BASE_URL?e.BI_UID_TOKEN?!0:!!(e.BI_LOGIN_DOMAIN&&e.BI_LOGIN_ID&&e.BI_LOGIN_PASSWORD):!1}function Ar(e,t,n){let r={Cookie:`uIdToken=${e}`,"User-Agent":"guanbi-mcp-server",...X(n)};return t.body!==void 0&&(r["Content-Type"]="application/json"),t.includeDeviceId&&(r["Device-ID"]=Rr),r}function kr(e,t,n){if(!e)return{};try{return JSON.parse(e)}catch{throw new O("ChatBI response is not valid JSON",{operation:n.operation,base_url:n.baseUrl,path:n.path,http_status:t.status,token_refreshed:n.tokenRefreshed,detail:Ct(e)},{retryableForBaseUrl:!0})}}function Pr(e){let t=yt(e);return typeof t=="number"&&![0,200].includes(t)||e.result==="fail"||e.success===!1}function vr(e,t,n,r){let i=yt(e),s=Nr(e),o=s||t||`ChatBI request failed with status ${n.status}`,a={operation:r.operation,base_url:r.baseUrl,path:r.path,http_status:n.status,chatbi_code:i,chatbi_message:s,token_refreshed:r.tokenRefreshed,detail:Ct(t)},u=Lr(o),c=!u&&Dr(n.status,i);return new O(o,a,{authExpired:c,retryableForBaseUrl:u||Ur(n.status,i)})}function xr(e,t){return!!(t&&e instanceof O&&e.retryableForBaseUrl)}function Mr(e){return e instanceof O&&e.authExpired}function Dr(e,t){return e===401||e===403||t===401||t===403||t===5001}function Ur(e,t){return[401,403,404,405].includes(e)||typeof t=="number"&&[401,403,404,405].includes(t)}function jr(e){return e instanceof O&&e.detail.http_status===200&&e.detail.chatbi_code===404&&e.detail.chatbi_message==="Message not found."}function yt(e){if(typeof e.code=="number")return e.code;let t=le(e.error);return typeof t?.status=="number"?t.status:void 0}function Nr(e){if(typeof e.message=="string"&&e.message.trim())return e.message;let t=le(e.error);return typeof t?.message=="string"&&t.message.trim()?t.message:void 0}function Lr(e){return/No static resource/i.test(e)}function le(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function qr(e,t){let n=le(e);if(!Array.isArray(n?.themes))throw new O("ChatBI list-theme response missing themes",{operation:t.operation,base_url:t.baseUrl,path:t.path,detail:"missing themes"},{retryableForBaseUrl:!0})}function Gr(e,t){let r=[...e.headers.getSetCookie?.()??[],...Hr(e.headers.get("set-cookie"))].map(s=>Oe(s.trim().match(/(?:^|;\s*)uIdToken=([^;]+)/)?.[1])).find(Boolean);if(r)return r;let i=Oe(e.headers.get("x-auth-token"));return i||Tt(t)}function Hr(e){return e?e.split(/,(?=\s*[^;,]+=)/):[]}function Oe(e){if(typeof e!="string")return;let t=e.trim();return t&&!/\s/.test(t)?t:void 0}function Tt(e){let t=le(e);if(t){for(let n of["uIdToken","authToken"]){let r=Oe(t[n]);if(r)return r}for(let n of["data","response"]){let r=Tt(t[n]);if(r)return r}}}function _t(e,t){return e instanceof O?e.detail:{operation:t,detail:e instanceof Error?e.message:String(e)}}function Ct(e,t=1e3){return e.length>t?`${e.slice(0,t)}...`:e}function Jr(e){let t=`${e.chatbi_message??""} ${e.detail??""}`;return/BI 登录失败|密码登录|sign-?in|login/i.test(t)?"login_failed":e.http_status===401||e.http_status===403||e.chatbi_code===401||e.chatbi_code===403?"permission_denied":/No static resource|not valid JSON/i.test(t)||e.http_status===404||e.http_status===405||e.chatbi_code===404||e.chatbi_code===405?"public_api_unreachable":"unknown"}function $r(e,t){let n=t.trim().toLowerCase(),r,i=[];for(let s of e){let o=s.theme_name.trim().toLowerCase();o===n?r=s:o.includes(n)&&i.push(s)}if(r)return r.theme_id;if(i.length===1)return i[0].theme_id;throw i.length>1?new Error(`\u4E3B\u9898\u540D\u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF1A${t}`):new Error(`\u672A\u627E\u5230\u4E3B\u9898\uFF1A${t}`)}function It(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>typeof t<"u"))}function Fr(e){if([e.final_status,e.answer_status,e.query_status].some(zr))throw new Error(`ChatBI query failed: ${Vr(e.query_context?.err_msg,e.query_context?.detail,e.query_context?.msg,e.answer_context?.detail,e.answer_context?.msg,"unknown failure")}`);if(!e.answer?.explain?.trim()&&!(e.query_result?.columns?.length||e.query_result?.preview?.length))throw new Error("ChatBI response missing query content")}function Vr(...e){return e.find(t=>typeof t=="string"&&t.trim())?.trim()}function zr(e){return typeof e=="string"&&e.trim().toLowerCase()==="failure"}function bt(e){let t=e-Date.now();if(t<=0)throw new Error("Insight request timed out");return t}async function Qr(e,t,n){let r=e-Date.now();if(r<=0)throw new Error(`Insight request timed out after ${n}ms`);await new Promise(i=>setTimeout(i,Math.min(t,r)))}var Z="8.2.0",ke=["search_metrics","list_metric_catalog","get_metric_detail","query_metric_data","search_metric_trees","get_metric_tree_detail","query_metric_tree_attribution"],Kr=["get_bi_capabilities","global_search",...ke,"execute_sql_query","get_dataset_detail","get_card_info","query_card_data","get_page_info"],Yr=6e4,Ae=new WeakMap;async function te(e,t){let n=Ae.get(e);return(!n||n.expiresAt<=Date.now())&&Ae.set(e,{expiresAt:Date.now()+Yr,promise:Xr(e,t).catch(r=>Wr(r,t))}),Ae.get(e).promise}function Bt(e){let t=!e.BI_BASE_URL,n="HTTP \u6A21\u5F0F\u4E0B execute_sql_query \u4F1A\u5728\u8C03\u7528\u65F6\u4F7F\u7528\u5F53\u524D\u7528\u6237 token \u5224\u65AD BI \u7248\u672C/\u80FD\u529B\u3002",r="HTTP \u6A21\u5F0F\u542F\u52A8\u671F\u5C1A\u672A\u89E3\u6790\u8BF7\u6C42\u8C03\u7528\u8005\u3002";return{ok:!t,error:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":void 0,versionSource:"api",dataVersion:e.BI_DATA_VERSION,service:ve(e,t?["get_bi_capabilities"]:Pe(e)),caller:{ok:!1,error:r,features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:r}},chatbi:ee(e,r)},features:{executeSqlQuery:{enabled:!t,minVersion:Z,reason:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":n}},metricPlatform:{registeredTools:t?[]:ke,readOnly:!0,lastError:t?"\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A\u7F3A\u5C11 BI_BASE_URL\u3002":void 0},chatbi:ee(e,"HTTP \u6A21\u5F0F\u542F\u52A8\u671F\u4E0D\u4F7F\u7528\u67D0\u4E2A\u7528\u6237 token \u63A2\u6D4B ChatBI \u80FD\u529B\u3002")}}async function St(e,t,n){let i=(await te(e,t)).features[n];if(!i.enabled)throw new Error(`\u5F53\u524D BI \u73AF\u5883\u4E0D\u652F\u6301 ${n}\uFF1A${i.reason??"\u80FD\u529B\u672A\u542F\u7528"}`)}function Wr(e,t){let n=e instanceof Error?e.message:String(e);return{ok:!1,error:n,versionSource:"api",features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:`\u65E0\u6CD5\u786E\u8BA4 BI \u80FD\u529B\uFF1A${n}`}},metricPlatform:{registeredTools:[],readOnly:!0,lastError:n},chatbi:ee(t,n),service:ve(t,Pe(t)),caller:{ok:!1,error:n,features:{executeSqlQuery:{enabled:!1,minVersion:Z,reason:`\u65E0\u6CD5\u786E\u8BA4 BI \u80FD\u529B\uFF1A${n}`}},chatbi:ee(t,n)}}}async function Xr(e,t){let n=ei(t);if(n.length)throw new Error(`\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF1A${n.join("\uFF1B")}\u3002`);let r=t.BI_DATA_VERSION?"env":"api",i=t.BI_DATA_VERSION?{dataVersion:t.BI_DATA_VERSION,capabilityVersion:t.BI_DATA_VERSION}:await ti(e),s=ni(i.capabilityVersion,Z),o=await Zr(t);return{ok:!0,appVersion:i.appVersion,dataVersion:i.dataVersion,versionSource:r,service:ve(t,Pe(t)),caller:{ok:!0,features:{executeSqlQuery:s},chatbi:o},features:{executeSqlQuery:s},metricPlatform:{registeredTools:ke,readOnly:!0},chatbi:o}}function Pe(e){let t=new Set(Kr);if(de(e)||e.MCP_TRANSPORT==="streamable-http")for(let n of new v(e).getRegisteredTools())t.add(n);return[...t]}function ve(e,t){return{mode:e.MCP_TRANSPORT??"stdio",toolList:t,boundBISite:{configured:!!e.BI_BASE_URL,baseUrl:e.BI_BASE_URL,publicPath:e.BI_PUBLIC_PATH}}}async function Zr(e){let t=new v(e);return de(e)?t.probe():ee(e,"\u7F3A\u5C11 BI_BASE_URL \u6216\u9274\u6743\u914D\u7F6E\u3002")}function ee(e,t){return{available:!1,registeredTools:de(e)?new v(e).getRegisteredTools():[],failureType:"unknown",triedBaseUrls:[],lastError:{operation:"probe",chatbi_message:t,detail:t}}}function ei(e){let t=[];if(e.BI_BASE_URL||t.push("\u7F3A\u5C11 BI_BASE_URL"),!e.BI_UID_TOKEN){let n=[["BI_LOGIN_DOMAIN",e.BI_LOGIN_DOMAIN],["BI_LOGIN_ID",e.BI_LOGIN_ID],["BI_LOGIN_PASSWORD",e.BI_LOGIN_PASSWORD]].filter(([,r])=>!r).map(([r])=>r);n.length&&t.push(`\u7F3A\u5C11\u9274\u6743\u914D\u7F6E\uFF1A\u8BF7\u914D\u7F6E BI_UID_TOKEN\uFF0C\u6216\u8865\u5168\u8D26\u53F7\u5BC6\u7801\u767B\u5F55\u914D\u7F6E\uFF08\u7F3A\u5C11 ${n.join("\u3001")}\uFF09`)}return t}async function ti(e){let t=await e.get("/api/server-version"),n=wt(t.version),r=wt(t.dataVersion)??n;if(!r)throw new Error("BI \u7248\u672C\u63A5\u53E3\u672A\u8FD4\u56DE version \u6216 dataVersion\u3002");return{appVersion:n,dataVersion:r,capabilityVersion:r}}function ni(e,t){let n=Et(e),r=Et(t);if(!r)throw new Error(`\u5185\u90E8\u914D\u7F6E\u9519\u8BEF\uFF1A\u65E0\u6CD5\u89E3\u6790\u6700\u4F4E\u7248\u672C ${t}\u3002`);if(!n)return{enabled:!1,minVersion:t,reason:`\u65E0\u6CD5\u4ECE\u7248\u672C\u5B57\u7B26\u4E32 "${e}" \u4E2D\u89E3\u6790\u4EA7\u54C1\u7248\u672C\uFF0C\u8BF7\u914D\u7F6E BI_DATA_VERSION\u3002`};let i=ri(n,r)>=0;return{enabled:i,minVersion:t,reason:i?void 0:`\u9700\u8981 BI ${t}+\uFF0C\u5F53\u524D\u7248\u672C\u4E3A ${e}\u3002`}}function Et(e){let t=e.match(/(\d+)\.(\d+)\.(\d+)/);if(t)return[Number(t[1]),Number(t[2]),Number(t[3])]}function ri(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function wt(e){return typeof e=="string"&&e.trim()?e.trim():void 0}var pe=class{constructor(t){this.config=t}config;cache=new Map;async exchange(t){let n=Rt(t),r=this.cache.get(this.cacheKey(n));if(r&&r.expiresAtMs>Date.now())return this.result(n,r.token,r.biExpireAt);let i=await this.fetchLoginIdToken(n);return this.cache.set(this.cacheKey(n),{token:i.token,expiresAtMs:this.resolveCacheExpiresAt(i.expireAt),biExpireAt:i.expireAt}),this.result(n,i.token,i.expireAt)}async exchangeUserProperty(t){let n=await this.fetchLoginIdByUserProperty(t);return this.exchange(n)}async refresh(t){return this.cache.delete(this.cacheKey(t)),(await this.exchange(t)).token}result(t,n,r){return{token:n,expireAt:r,refresh:()=>this.refresh(t)}}async fetchLoginIdByUserProperty(t){let n=ii(t);if(!this.config.BI_BASE_URL)throw this.debugError("BI_BASE_URL is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});if(!this.config.BI_APP_TOKEN)throw this.debugError("BI_APP_TOKEN is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});let r=this.config.BI_USER_PROPERTY_KEY?.trim();if(!r)throw this.debugError("BI_USER_PROPERTY_KEY is required for user property identity exchange.",{operation:"userPropertyLookup",request:{userPropertyValue:n}});let i=this.buildUrl("/public-api/user/properties/list"),s={token:this.config.BI_APP_TOKEN,userPropertyKey:r,userPropertyValue:n,enabled:!0,offset:0,limit:2},o;try{o=await fetch(i,{method:"POST",headers:G({"Content-Type":"application/json","raw-backend-response":"TRUE"},this.config.BI_REQUEST_METADATA),body:JSON.stringify(s),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}catch(p){throw this.debugError(`BI user property lookup request failed: ${p instanceof Error?p.message:String(p)}`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},error:p instanceof Error?p.message:String(p)},[this.config.BI_APP_TOKEN])}let a=await o.text(),u=Ot(a);if(!o.ok||At(u))throw this.debugError(`BI user property lookup failed: HTTP ${o.status} ${xe(a,[this.config.BI_APP_TOKEN,r,n])}`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},response:{status:o.status,body:a}},[this.config.BI_APP_TOKEN]);let c=u?.response?.list??[],d=u?.response?.total??c.length;if(d!==1||c.length!==1)throw this.debugError(`BI user property lookup must match exactly one user: matched ${d} user(s) for ${r}.`,{operation:"userPropertyLookup",request:{method:"POST",url:i,body:s},response:{status:o.status,total:d,listCount:c.length,matchedLoginIds:c.map(p=>p.loginId).filter(Boolean)}},[this.config.BI_APP_TOKEN]);return Rt(c[0]?.loginId??"")}async fetchLoginIdToken(t){if(!this.config.BI_BASE_URL)throw this.debugError("BI_BASE_URL is required for loginId identity exchange.",{operation:"loginIdSignIn",request:{loginId:t}});if(!this.config.BI_APP_TOKEN)throw this.debugError("BI_APP_TOKEN is required for loginId identity exchange.",{operation:"loginIdSignIn",request:{loginId:t}});let n=this.buildUrl("/public-api/user/loginId/sign-in"),r={token:this.config.BI_APP_TOKEN,loginId:t},i;try{i=await fetch(n,{method:"POST",headers:G({"Content-Type":"application/json","raw-backend-response":"TRUE"},this.config.BI_REQUEST_METADATA),body:JSON.stringify(r),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}catch(u){throw this.debugError(`BI loginId token exchange request failed: ${u instanceof Error?u.message:String(u)}`,{operation:"loginIdSignIn",request:{method:"POST",url:n,body:r},error:u instanceof Error?u.message:String(u)},[this.config.BI_APP_TOKEN])}let s=await i.text(),o=Ot(s),a=o?.response?.token?.trim();if(!i.ok||At(o)||!a)throw this.debugError(`BI loginId token exchange failed: HTTP ${i.status} ${xe(s,[this.config.BI_APP_TOKEN,a,t])}`,{operation:"loginIdSignIn",request:{method:"POST",url:n,body:r},response:{status:i.status,body:s}},[this.config.BI_APP_TOKEN,a]);return{token:a,expireAt:o?.response?.expireAt}}buildUrl(t){let n=t.startsWith("/")?t:`/${t}`;return`${this.config.BI_BASE_URL}${this.config.BI_PUBLIC_PATH}${n}`}cacheKey(t){return`${this.config.BI_BASE_URL??""}${this.config.BI_PUBLIC_PATH}\0${t}`}resolveCacheExpiresAt(t){let n=Date.now()+this.config.BI_IDENTITY_TOKEN_CACHE_TTL_MS,r=si(t);return r?Math.min(n,r):n}debugError(t,n,r=[]){if(!ai(this.config))return new Error(t);let i=Me(n,[this.config.BI_APP_TOKEN,...r]);return console.error(JSON.stringify({identityExchangeDebug:i})),new Error(`${t}
|
|
3
3
|
identity_debug=${JSON.stringify(i,null,2)}`)}};function Rt(e){let t=e.trim();if(!t)throw new Error("GuanBI loginId is required for loginId identity exchange.");return t}function ii(e){let t=e.trim();if(!t)throw new Error("BI user property value is required for user property identity exchange.");return t}function Ot(e){if(e.trim())try{return JSON.parse(e)}catch{return}}function At(e){return!e||e.result&&!["ok","success"].includes(e.result.toLowerCase())?!0:e.success===!1}function si(e){if(!e)return;let t=e.replace(" ","T"),n=Date.parse(t);return Number.isFinite(n)?n:void 0}function xe(e,t){let n=t.filter(r=>!!r).reduce((r,i)=>r.split(i).join("[redacted]"),e);return ui(n)}function Me(e,t){let n=t.filter(r=>!!r);return typeof e=="string"?xe(e,n):Array.isArray(e)?e.map(r=>Me(r,n)):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).map(([r,i])=>[r,oi(r)?"[redacted]":Me(i,n)]))}function oi(e){return["token","authorization","cookie","uidtoken","uIdToken".toLowerCase()].includes(e.toLowerCase())}function ai(e){return["1","true","yes","on"].includes(e.BI_IDENTITY_DEBUG?.trim().toLowerCase()??"")}function ui(e,t=1e3){return e.length>t?`${e.slice(0,t)}\u2026`:e}function ci(e){return{transport:"stdio",biUidToken:e.BI_UID_TOKEN,audit:{}}}function Pt(e){return{resolve:()=>ci(e)}}function me(e){let t=L(e,"x-guanbi-uid-token")?.trim();if(!t)throw new Error("\u7F3A\u5C11 GuanBI \u7528\u6237\u4EE4\u724C\uFF1A\u8BF7\u901A\u8FC7 X-GuanBI-Uid-Token \u4F20\u5165\u5F53\u524D\u7528\u6237 uIdToken\u3002");return{transport:"streamable-http",biUidToken:t,audit:Ue(e)}}function vt(e,t={}){let n=e?new pe(e):void 0,r=t.exchangeLoginId??t.exchange??(n?n.exchange.bind(n):void 0),i=t.exchangeUserProperty??(n?n.exchangeUserProperty.bind(n):void 0);return{resolve:async s=>{if(!s?.requestInfo?.headers)return{transport:"streamable-http",audit:{}};let o=s.requestInfo.headers;if(L(o,"x-guanbi-uid-token")?.trim()||!e)return me(o);let u=e.BI_LOGIN_ID_HEADER,c=u?ne(L(o,u)):void 0;if(c){let g=await r?.(c);return g?{transport:"streamable-http",biUidToken:g.token,biUidTokenRefresh:g.refresh,loginId:c,audit:Ue(o)}:me(o)}let d=e.BI_USER_PROPERTY_HEADER,p=d?ne(L(o,d)):void 0;if(p){let g=await i?.(p);return g?{transport:"streamable-http",biUidToken:g.token,biUidTokenRefresh:g.refresh,audit:Ue(o)}:me(o)}throw di(o,e)}}}function L(e,t){if(e instanceof Headers)return e.get(t)??void 0;let n=e.get;if(typeof n=="function")return n.call(e,t)??void 0;let r=t.toLowerCase();for(let[i,s]of Object.entries(e))if(i.toLowerCase()===r)return Array.isArray(s)?s[0]:s}function ne(e){return e?.trim()||void 0}function Ue(e){return{tenantId:ne(L(e,"x-tenant-id")),endUserId:ne(L(e,"x-end-user-id")),traceId:ne(L(e,"x-trace-id"))}}function di(e,t){let n="\u7F3A\u5C11 GuanBI \u7528\u6237\u4EE4\u724C\uFF1A\u8BF7\u901A\u8FC7 X-GuanBI-Uid-Token \u4F20\u5165\u5F53\u524D\u7528\u6237 uIdToken\u3002";if(!gi(t))return new Error(n);let r={operation:"resolveHttpCallerContext",expectedIdentityHeaders:li(e,t),receivedHeaderNames:pi(e),receivedIdentityLikeHeaders:kt(Object.fromEntries(je(e).filter(([i])=>fi(i.toLowerCase()))),["x-guanbi-uid-token",t.BI_LOGIN_ID_HEADER,t.BI_USER_PROPERTY_HEADER]),receivedHeaders:kt(e,["x-guanbi-uid-token",t.BI_LOGIN_ID_HEADER,t.BI_USER_PROPERTY_HEADER])};return console.error(JSON.stringify({identityExchangeDebug:r})),new Error(`${n}
|
|
4
4
|
identity_debug=${JSON.stringify(r,null,2)}`)}function li(e,t){return[{source:"uidToken",name:"x-guanbi-uid-token",present:De(e,"x-guanbi-uid-token")},...t.BI_LOGIN_ID_HEADER?[{source:"loginId",name:t.BI_LOGIN_ID_HEADER,present:De(e,t.BI_LOGIN_ID_HEADER)}]:[],...t.BI_USER_PROPERTY_HEADER?[{source:"userProperty",name:t.BI_USER_PROPERTY_HEADER,present:De(e,t.BI_USER_PROPERTY_HEADER),userPropertyKey:t.BI_USER_PROPERTY_KEY}]:[]]}function De(e,t){return L(e,t)!==void 0}function pi(e){return[...new Set(je(e).map(([t])=>t.toLowerCase()))].sort()}function kt(e,t){let n=new Set(t.filter(r=>!!r).map(r=>r.toLowerCase()));return Object.fromEntries(je(e).map(([r,i])=>{let s=r.toLowerCase();return mi(s)?[s,"<redacted>"]:[s,n.has(s)?i:"<present>"]}))}function je(e){if(e instanceof Headers)return[...e.entries()];let t=e.entries;return typeof t=="function"?[...t.call(e)]:Object.entries(e).filter(([,n])=>n!==void 0).map(([n,r])=>[n,Array.isArray(r)?r.join(","):String(r)])}function mi(e){return["authorization","cookie","set-cookie","x-guanbi-uid-token"].includes(e)}function fi(e){return e.startsWith("x-")||e.includes("auth")||e.includes("login")||e.includes("token")||e.includes("uid")||e.includes("user")}function gi(e){return["1","true","yes","on"].includes(e.BI_IDENTITY_DEBUG?.trim().toLowerCase()??"")}var fe=class{constructor(t){this.config=t;this.token=t.BI_UID_TOKEN}config;token;async get(t,n){return this.request("GET",t,void 0,n)}async post(t,n,r){return this.request("POST",t,n,r)}async put(t,n,r){return this.request("PUT",t,n,r)}async getText(t){let n=await this.ensureToken(),r=await fetch(this.buildUrl(t),{method:"GET",headers:G({"raw-backend-response":"TRUE",Cookie:`uIdToken=${n}`},this.config.BI_REQUEST_METADATA),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)});if(this.shouldRefreshToken(r)){let s=await this.refreshToken();r=await fetch(this.buildUrl(t),{method:"GET",headers:G({"raw-backend-response":"TRUE",Cookie:`uIdToken=${s}`},this.config.BI_REQUEST_METADATA),signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}let i=await r.text();if(!r.ok)throw new Error(`BI \u8BF7\u6C42\u5931\u8D25\uFF1AGET ${t} HTTP ${r.status} ${xt(i)}`);return this.refreshTokenFromResponse(r),i}async request(t,n,r,i){let s=await this.ensureToken(),o=await this.fetchWithToken(t,n,s,r,i);if(this.shouldRefreshToken(o)){let u=await this.refreshToken();o=await this.fetchWithToken(t,n,u,r,i)}let a=await o.text();if(!o.ok)throw new Error(`BI \u8BF7\u6C42\u5931\u8D25\uFF1A${t} ${n} HTTP ${o.status} ${xt(a)}`);return this.refreshTokenFromResponse(o),hi(a)}async fetchWithToken(t,n,r,i,s){return fetch(this.buildUrl(n),{method:t,headers:G({"Content-Type":"application/json","raw-backend-response":"TRUE",Cookie:`uIdToken=${r}`,...s?.headers},this.config.BI_REQUEST_METADATA),body:t==="POST"||t==="PUT"?JSON.stringify(i??{}):void 0,signal:AbortSignal.timeout(this.config.BI_REQUEST_TIMEOUT_MS)})}async ensureToken(){if(this.token)return this.token;let t=await ce(this.config);return this.token=t.token,t.token}async refreshToken(){if(this.config.BI_UID_TOKEN_REFRESH){let t=await this.config.BI_UID_TOKEN_REFRESH();return this.token=t,t}return this.token=void 0,this.ensureToken()}refreshTokenFromResponse(t){let n=Ii(t);!n||n===this.token||(this.token=n)}shouldRefreshToken(t){return(!!this.config.BI_UID_TOKEN_REFRESH||this.hasPasswordLogin())&&t.status===401}hasPasswordLogin(){return!!(this.config.BI_LOGIN_DOMAIN&&this.config.BI_LOGIN_ID&&this.config.BI_LOGIN_PASSWORD)}buildUrl(t){let n=t.startsWith("/")?t:`/${t}`;return`${this.config.BI_BASE_URL}${this.config.BI_PUBLIC_PATH}${n}`}};function hi(e){if(!e)return;let t=JSON.parse(e);if(!_i(t))return t;if(t.result&&!["ok","success"].includes(t.result.toLowerCase()))throw new Error(`BI \u8FD4\u56DE\u9519\u8BEF\uFF1A${t.message??JSON.stringify(t.error??t)}`);if(t.success===!1)throw new Error(`BI \u8FD4\u56DE\u9519\u8BEF\uFF1A${t.message??JSON.stringify(t.error??t)}`);return"response"in t?t.response:t}function _i(e){return!e||typeof e!="object"||Array.isArray(e)?!1:"response"in e||"result"in e||"success"in e}function Ii(e){return bi(e.headers)??Ti(e.headers)}function bi(e){return[...e.getSetCookie?.()??[],...yi(e.get("set-cookie"))].map(n=>Mt(n.trim().match(/(?:^|;\s*)uIdToken=([^;]+)/)?.[1])).find(Boolean)}function yi(e){return e?e.split(/,(?=\s*[^;,]+=)/):[]}function Ti(e){return Mt(e.get("x-auth-token"))}function Mt(e){if(typeof e!="string")return;let t=e.trim();return t&&!/\s/.test(t)?t:void 0}function xt(e,t=1e3){return e.length>t?`${e.slice(0,t)}...`:e}var ge=class{constructor(t,n={}){this.baseConfig=t;this.options=n}baseConfig;options;stdioClient;create(t,n){let r=this.resolveRequestMetadata(n);if(t.transport==="stdio"&&this.stdioClient)return{...this.stdioClient,config:{...this.stdioClient.config,BI_REQUEST_METADATA:r}};let i=this.resolveConfig(t,t.transport==="stdio"?this.resolveRequestMetadata(void 0):r),s={client:this.options.clientFactory?.(i)??new fe(i),config:{...i,BI_REQUEST_METADATA:r},context:t};return t.transport==="stdio"&&(this.stdioClient={...s,config:i}),s}resolveConfig(t,n){let r=t.biUidToken??(t.transport==="stdio"?this.baseConfig.BI_UID_TOKEN:void 0);return{...this.baseConfig,BI_UID_TOKEN:r,BI_UID_TOKEN_REFRESH:t.transport==="streamable-http"?t.biUidTokenRefresh:void 0,BI_LOGIN_DOMAIN:t.transport==="stdio"?this.baseConfig.BI_LOGIN_DOMAIN:"",BI_LOGIN_ID:t.transport==="stdio"?this.baseConfig.BI_LOGIN_ID:void 0,BI_LOGIN_PASSWORD:t.transport==="stdio"?this.baseConfig.BI_LOGIN_PASSWORD:void 0,BI_REQUEST_METADATA:n}}resolveRequestMetadata(t){let n=this.options.requestMetadata;if(n)return t?{...n,command:t}:{...n}}};var Dt={endpoint:"https://www.google-analytics.com/mp/collect",measurementId:"G-800H8JWDPP",apiSecret:"poAwpMEhQteDl1rXKtNIqg",eventName:"guanbi_mcp_tool_call",clientId:"0000000000.0000000000",sessionId:1,engagementTimeMsec:1,timeoutMs:3e3,maxResponseBytes:1024},he=class{serviceDomain;appVersion;enabled;sender;now;constructor({config:t,appVersion:n,sender:r=wi(),now:i=Date.now}){this.serviceDomain=Si(t.BI_BASE_URL),this.appVersion=n,this.enabled=Bi(t),this.sender=r,this.now=i}observeToolCallStart(t){return{toolName:t,startedAtMs:this.now()}}observeToolCallEnd(t,n){if(!this.enabled||!this.serviceDomain)return;let r={service_domain:this.serviceDomain,app_version:this.appVersion,tool:t.toolName,success:n.success,duration_ms_bucket:Ri(this.now()-t.startedAtMs),error_type:n.success?"none":Ai(n.error)};try{Promise.resolve(this.sender(r)).catch(()=>{})}catch{}}};function Ci(e=Dt){return t=>Ei(t,e)}async function Ei(e,t=Dt){try{if(!t.endpoint||!t.measurementId||!t.apiSecret||!e.tool)return;let n=new URL(t.endpoint);n.searchParams.set("measurement_id",t.measurementId),n.searchParams.set("api_secret",t.apiSecret);let r=JSON.stringify({client_id:t.clientId,events:[{name:t.eventName,params:{service_domain:e.service_domain,app_version:e.app_version,tool:e.tool,success:e.success,duration_ms_bucket:e.duration_ms_bucket,error_type:e.error_type,session_id:t.sessionId,engagement_time_msec:t.engagementTimeMsec}}]}),i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:r,signal:AbortSignal.timeout(t.timeoutMs)});await Oi(i,t.maxResponseBytes)}catch{}}function wi(){return ki(process.env)?()=>{}:Ci()}function Bi(e){let t=e.GUANBI_MCP_USAGE_STATS?.trim().toLowerCase();return t?["0","false","off","no"].includes(t)?!1:(["1","true","on","yes"].includes(t),!0):!0}function Ut(e,t,n){return(async(...r)=>{let i=n.observeToolCallStart(e);try{let s=await t(...r);return n.observeToolCallEnd(i,{success:!0}),s}catch(s){throw n.observeToolCallEnd(i,{success:!1,error:s}),s}})}function Si(e){if(e)try{return new URL(e).hostname}catch{return}}function Ri(e){return e<1e3?"<1s":e<5e3?"1-5s":e<3e4?"5-30s":e<12e4?"30-120s":">120s"}async function Oi(e,t){let n=e.body?.getReader();if(!n)return;let r=0;try{for(;r<t;){let{done:i,value:s}=await n.read();if(i)return;r+=s.byteLength}}finally{await n.cancel().catch(()=>{})}}function Ai(e){let t=e instanceof Error?e.message:String(e);return/校验|验证|validation|invalid|schema|zod/i.test(t)?"validation":/鉴权|登录|认证|unauthorized|unauthenticated|401|auth/i.test(t)?"auth":/权限|forbidden|permission|403/i.test(t)?"permission":/timeout|network|fetch|econn|enotfound|socket/i.test(t)?"network":/BI 请求失败|BI 返回错误|HTTP \d{3}/i.test(t)?"bi_error":"unknown"}function ki(e){return e.NODE_ENV==="test"||e.VITEST==="true"}var _e=class{constructor(t,n,r=new ae){this.callerContextResolver=t;this.clientFactory=n;this.auditLogger=r}callerContextResolver;clientFactory;auditLogger;async run(t,n,r){let i=Date.now(),s=await this.callerContextResolver.resolve(n),o=this.clientFactory.create(s,r);try{let a=await gt(o.config.BI_REQUEST_METADATA,()=>t(o));if(r){let u=Pi(a)?"error":"success";this.auditLogger.record(Re(r,s,i,u,a))}return a}catch(a){throw r&&this.auditLogger.record(Re(r,s,i,"error",a)),a}}};function Pi(e){return!!(e&&typeof e=="object"&&e.isError===!0)}function M(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}function C(e){let t=jt(e);return{content:[{type:"text",text:JSON.stringify(t,null,2)}],structuredContent:t}}function H(e){let t=jt(e);return{content:[{type:"text",text:JSON.stringify(t,null,2)}],isError:!0}}function jt(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}var Nt={};async function Lt(e,t){return M(await te(e,t))}import{z as T}from"zod";var J=class extends Error{constructor(n,r){super(n.message,{cause:r});this.detail=n;this.name="MetricPlatformRequestError"}detail},D=class{constructor(t,n){this.client=t;this.config=n}client;config;contextHeadersPromise;listProjects(){return this.get("listProjects","/api/metric-platform/projects")}searchMetrics(t){let n=_({projectId:t.projectId,dirId:t.dirId,status:t.status,nameLike:t.keyword,subTypes:t.subTypes?.join(","),orderBy:t.orderBy});return this.post("searchMetrics","/api/metric-platform/metrics",n)}listMetricFullTree(t){return this.get("listMetricFullTree",Le("/api/metric-platform/metrics/full-tree",{projectId:t.projectId,nameLike:t.keyword}))}listMetricDirectoryTree(t){return this.get("listMetricDirectoryTree",Le("/api/directory/METRIC_PLATFORM/unauthorized-tree",{projectId:t}))}getMetricDetail(t){return this.get("getMetricDetail",`/api/metric-platform/metrics/${encodeURIComponent(t)}`)}getMetricLineage(t,n){return this.post("getMetricLineage",`/api/resource-atlas/${encodeURIComponent(t)}`,{resourceTypeName:n})}queryMetricData(t){let{metricId:n,metricName:r,...i}=t;return this.post("queryMetricData","/api/metric-platform/metric-data/v2",_(i))}getCardEditSession(t){return this.get("getCardEditSession",`/api/card/${encodeURIComponent(t)}/edit/session`)}getCardEditMeta(t){return this.get("getCardEditMeta",`/api/card/${encodeURIComponent(t)}/edit`)}modifyCardEditMeta(t,n,r){return this.put("modifyCardEditMeta",`/api/oriput/card/${encodeURIComponent(t)}/edit/${encodeURIComponent(n)}/modify`,r)}queryCardEditData(t,n,r){return this.post("queryCardEditData",`/api/card/${encodeURIComponent(t)}/edit/${encodeURIComponent(n)}/data`,r)}searchMetricTrees(t){return this.get("searchMetricTrees",Le("/api/metric-platform/metric-tree/search",{nameLike:t.keyword,projectId:t.projectId,parentDirId:t.parentDirId,orderBy:t.orderBy}))}async getMetricTreeDetail(t){return this.get("getMetricTreeDetail",`/api/metric-platform/metric-tree/${encodeURIComponent(t)}`,await this.metricTreeHeaders(t,"dimension"))}async queryMetricTreeDrill(t,n){return this.post("queryMetricTreeDrill",`/api/metric-platform/metric-tree/${encodeURIComponent(t)}/drill`,n,await this.metricTreeHeaders(t,"dimension"))}async queryMetricTreeDecompose(t,n){return this.post("queryMetricTreeDecompose",`/api/metric-platform/metric-tree/${encodeURIComponent(t)}/metric-decompose`,n,await this.metricTreeHeaders(t,"metric"))}async put(t,n,r,i){try{return await this.client.put(n,r,i?{headers:i}:void 0)}catch(s){throw Ne(t,n,s)}}async get(t,n,r){try{return await this.client.get(n,r?{headers:r}:void 0)}catch(i){throw Ne(t,n,i)}}async post(t,n,r,i){try{return await this.client.post(n,r,i?{headers:i}:void 0)}catch(s){throw Ne(t,n,s)}}async metricTreeHeaders(t,n){return{Referer:`${this.config.BI_BASE_URL??""}${this.config.BI_PUBLIC_PATH}/metrics-store/hierarchy/${encodeURIComponent(t)}/edit/${n}`,...await this.contextHeaders()}}async contextHeaders(){return this.contextHeadersPromise||(this.contextHeadersPromise=this.resolveContextHeaders()),this.contextHeadersPromise}async resolveContextHeaders(){let t={};if(this.config.BI_LOGIN_DOMAIN&&(t["x-dom-id"]=K(this.config.BI_LOGIN_DOMAIN)),this.config.BI_LOGIN_ID&&(t["user-id"]=K(this.config.BI_LOGIN_ID)),t["x-dom-id"]&&t["user-id"])return t;try{let n=await this.get("getUserProfile","/api/user/profile"),r=qt(n.domId,n.domainId,n.domain,n.dom_id),i=qt(n.email,n.loginId,n.userId,n.uId,n.uid);!t["x-dom-id"]&&r&&(t["x-dom-id"]=K(r)),!t["user-id"]&&i&&(t["user-id"]=K(i))}catch{}return t["x-dom-id"]||(t["x-dom-id"]=K(this.config.BI_LOGIN_DOMAIN||"guanbi")),t["user-id"]||(t["user-id"]=K(this.config.BI_LOGIN_ID||"unknown")),t}};function Ne(e,t,n){let r=n instanceof Error?n.message:String(n),i=r.match(/\bHTTP\s+(\d{3})\b/);return new J({operation:e,path:t,status:i?Number(i[1]):void 0,message:r},n)}function Le(e,t){let n=new URLSearchParams;for(let[i,s]of Object.entries(t))s!==void 0&&s!==""&&n.set(i,s);let r=n.toString();return r?`${e}?${r}`:e}function _(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function K(e){return Buffer.from(e,"utf8").toString("base64")}function qt(...e){for(let t of e)if(typeof t=="string"&&t.trim())return t.trim()}var vi=T.enum(["BT","CLOSE_BT_OPEN","OPEN_BT_CLOSE","OPEN_BT_OPEN","GT","GE","LT","LE","EQ","NE","IN","NI","IS_NULL","NOT_NULL","CONTAINS","NOT_CONTAINS","STARTSWITH","ENDSWITH","NOT_STARTSWITH","NOT_ENDSWITH","STARTSWITH_USER_PROPERTIES","STARTSWITH_GLOBAL_PARAMS"]),Gt=new Set(["BT","CLOSE_BT_OPEN","OPEN_BT_CLOSE","OPEN_BT_OPEN"]),Ge=new Set(["IS_NULL","NOT_NULL"]),xi=T.object({field:T.string().min(1).describe("\u7B5B\u9009\u5B57\u6BB5\u540D\u79F0\u3001\u522B\u540D\u6216\u5B57\u6BB5 ID\u3002"),operator:vi.describe("BI \u539F\u751F\u7B5B\u9009\u64CD\u4F5C\u7B26\uFF0C\u4F8B\u5982 EQ/NI/GE/BT/CONTAINS\u3002"),values:T.array(T.union([T.string(),T.number(),T.boolean()])).optional().describe("\u7B5B\u9009\u503C\u3002IS_NULL/NOT_NULL \u4E0D\u9700\u8981\u4F20\u503C\u3002"),fd_id:T.string().min(1).optional().describe("\u5DF2\u77E5\u5B57\u6BB5 ID \u65F6\u53EF\u76F4\u63A5\u6307\u5B9A\u3002")}).superRefine((e,t)=>{let n=e.values?.length??0;Ge.has(e.operator)&&n>0&&t.addIssue({code:T.ZodIssueCode.custom,path:["values"],message:`${e.operator} \u64CD\u4F5C\u7B26\u4E0D\u63A5\u53D7\u7B5B\u9009\u503C\u3002`}),Gt.has(e.operator)&&n!==2&&t.addIssue({code:T.ZodIssueCode.custom,path:["values"],message:`${e.operator} \u64CD\u4F5C\u7B26\u9700\u8981\u6070\u597D 2 \u4E2A\u503C\u3002`}),!Gt.has(e.operator)&&!Ge.has(e.operator)&&n<1&&t.addIssue({code:T.ZodIssueCode.custom,path:["values"],message:`${e.operator} \u64CD\u4F5C\u7B26\u81F3\u5C11\u9700\u8981 1 \u4E2A\u503C\u3002`})}),Ft={cd_id:T.string().min(1).describe("\u5361\u7247 ID\u3002"),filters:T.array(xi).optional().describe("\u7ED3\u6784\u5316\u7B5B\u9009\u6761\u4EF6\u3002\u4E0D\u652F\u6301 CLI \u98CE\u683C\u7B5B\u9009\u5B57\u7B26\u4E32\u3002"),columns:T.array(T.string().min(1)).optional().describe("\u5BF9\u5DF2\u5C55\u5E73\u7ED3\u679C\u505A\u672C\u5730\u5217\u88C1\u526A\uFF0C\u4E0D\u53C2\u4E0E BI \u67E5\u8BE2\u8BED\u4E49\u3002"),limit:T.number().int().positive().max(1e4).optional().default(100).describe("\u6700\u591A\u8FD4\u56DE\u884C\u6570\uFF0C\u9ED8\u8BA4 100\uFF0C\u4E0A\u9650 10000\u3002"),raw:T.boolean().optional().describe("\u662F\u5426\u8FD4\u56DE\u539F\u59CB\u54CD\u5E94\u3002")},Vt={summary:T.unknown().optional(),columns:T.array(T.unknown()).optional(),rows:T.array(T.unknown()).optional(),diagnostic:T.unknown().optional(),raw:T.unknown().optional(),status:T.string().optional()};async function zt(e,t){try{let n=t.limit??100,r=await e.get(`/api/card/${encodeURIComponent(t.cd_id)}`),i=Ui(r);if(i==="TEXT")return Mi(t.cd_id,r,t.columns,t.raw);let s=Vi(t.filters??[],Wi(r),i);if("unsupported"in s)return Di("query_card_data",s.unsupported);let o=i==="CHART"?await Ni(e,t.cd_id,n,s.filters):await ji(e,Qt(t.cd_id,i,n,s.filters)),{endpoint:a,requestBody:u}=o.requests[0],c=o.data,d=i==="CHART"?qi(I(c.chartMain)):$i(c),p=Wt(d.slice(0,n),t.columns);return C({summary:_({cd_id:t.cd_id,card_type:i,chart_type:i==="CHART"?S(I(r.content).chartType):void 0,row_count:p.length,truncated:Zi(i,c,p.length)}),columns:Xt(p),rows:p,diagnostic:{mode:Li(i),card_type:i,endpoint:a,request_body:u,request_count:o.requests.length,request_bodies:o.requests.length>1?o.requests.map(g=>g.requestBody):void 0,raw_returned:t.raw===!0},raw:t.raw?o.raw:void 0})}catch(n){return H({status:"error",diagnostic:es("query_card_data",n)})}}function Mi(e,t,n,r){let i=I(t.content),s=Fi(i),o=Wt(s?[{content:s}]:[],n);return C({summary:{cd_id:e,card_type:"TEXT",row_count:o.length,truncated:!1},columns:Xt(o),rows:o,diagnostic:{mode:"text_card_content",card_type:"TEXT",endpoint:`/api/card/${encodeURIComponent(e)}`,raw_returned:r===!0},raw:r?t:void 0})}function Di(e,t){return C({status:"unsupported",diagnostic:{tool:e,...t}})}function Ui(e){let t=S(e.cdType).toUpperCase();if(t==="SELECTOR"){let n=S(I(e.content).selectorType).toUpperCase();return n==="TREE"||n==="TREE_SELECTOR"?"TREE_SELECTOR":"SELECTOR"}return t==="TREE_SELECTOR"?"TREE_SELECTOR":t==="TEXT"?"TEXT":"CHART"}function Qt(e,t,n,r,i=0){let s=encodeURIComponent(e);return t==="SELECTOR"?{endpoint:`/api/selector/${s}/data`,requestBody:_({fieldQuery:{offset:0,limit:n},filters:r.length?r:void 0})}:t==="TREE_SELECTOR"?{endpoint:`/api/treeSelector/${s}/data`,requestBody:_({limit:n,filters:r.length?r:void 0})}:{endpoint:`/api/card/${s}/data`,requestBody:_({view:"GRID",isUniversalStructure:!0,offset:i>0?i:void 0,limit:n,filters:r.length?r:void 0})}}async function ji(e,t){let n=await e.post(t.endpoint,t.requestBody);return{raw:n,data:Kt(n),requests:[t]}}async function Ni(e,t,n,r){let s=[],o=[],a,u=0,c,d=!1,p=!1;for(;u<n;){let y=Math.min(1e3,n-u),R=Qt(t,"CHART",y,r,u);s.push(R);let P=await e.post(R.endpoint,R.requestBody);o.push(P);let Q=Kt(P),W=I(Q.chartMain);if(!Object.keys(W).length)return{raw:P,data:Q,requests:s};a?Gi(I(a.chartMain),W):a=ts(Q);let Se=Hi(W);u+=Se,c=$e(W.count)??c;let lt=Je(W.hasMoreData);if(p=lt!==void 0,d=lt??!1,Se===0||Se<y||c!==void 0&&u>=c||p&&!d)break}let g=a??{},b=I(g.chartMain);return Object.keys(b).length&&(b.offset=0,b.limit=n,b.hasMoreData=c!==void 0?u<c:d),{raw:o.length>1?{pages:o,merged:g}:o[0],data:g,requests:s}}function Li(e){return e==="SELECTOR"?"selector_card_data":e==="TREE_SELECTOR"?"tree_selector_card_data":"chart_card_data"}function Kt(e){let t=I(e),n=I(t.data),r=I(I(t.content).data);return Object.keys(n).length?n:Object.keys(r).length?r:t}function qi(e){if(!Object.keys(e).length)return[];let t=I(e.row),n=I(e.column),r=k(t.data??t.values),i=k(e.data),s=re(t.fields??t.meta).map(He).filter(Boolean),o=Ji(n),a=ns([...s,...o]),u=Math.max(r.length,i.length),c=[];for(let d=0;d<u;d+=1){let p=[];p.push(...k(r[d]).map($t)),p.push(...k(i[d]).map($t)),p.length&&c.push(Object.fromEntries(p.map((g,b)=>[a[b]??`column_${b+1}`,g])))}return c}function Gi(e,t){qe(e,t,"data");let n=I(e.row),r=I(t.row);qe(n,r,"data"),qe(n,r,"values")}function qe(e,t,n){let r=k(t[n]);r.length&&(e[n]=[...k(e[n]),...r])}function Hi(e){let t=k(e.data);if(t.length)return t.length;let n=I(e.row);return k(n.data).length||k(n.values).length}function Ji(e){let n=k(e.data??e.values).map((r,i)=>{let s=k(r).map(Yt).filter(Boolean).join("/");return s||He(re(e.fields??e.meta)[i])||`metric_${i+1}`}).filter(Boolean);return n.length?n:re(e.fields??e.meta).map(He).filter(Boolean)}function $i(e){return re(e.result)}function Fi(e){let n=k(I(e.body).blocks).map(r=>S(I(r).text)).filter(r=>r!=="");return n.length?n.join(`
|
|
5
5
|
`):S(e.text)}function Vi(e,t,n){let r=[];for(let i of e){let s=Ki(t,i.field,i.fd_id);if("unsupported"in s)return{unsupported:s.unsupported};r.push(_({name:s.field.name,fdId:s.field.fdId,fdType:s.field.fdType,filterLevel:n==="CHART"?Qi(s.field.metaType):void 0,filterType:i.operator,filterValue:zi(i)}))}return{filters:r}}function zi(e){return Ge.has(e.operator)?[]:(e.values??[]).map(S)}function Qi(e){return e.toUpperCase()==="METRIC"?"AGGREGATION":"DETAIL"}function Ki(e,t,n){let r=Yi(e,t,n);if(!r)return{unsupported:{capability:"unsupported_filter_field",parameter:t,message:`\u7B5B\u9009\u5B57\u6BB5\u65E0\u6CD5\u4ECE\u5F53\u524D\u5361\u7247\u4E0A\u4E0B\u6587\u89E3\u6790\uFF1A${t}`,supported_fields:e.map(c=>_({name:S(c.name),fd_id:S(c.fd_id),meta_type:S(c.meta_type)}))}};let i=S(r.name),s=S(r.fd_id),o=S(r.fd_type),a=S(r.meta_type).toUpperCase(),u=[i?void 0:"name",s?void 0:"fdId",o?void 0:"fdType",a?void 0:"metaType"].filter(c=>!!c);return u.length?{unsupported:{capability:"unsupported_filter_field",parameter:t,message:`\u7B5B\u9009\u5B57\u6BB5\u7F3A\u5C11\u5FC5\u8981 BI \u5143\u4FE1\u606F\uFF1A${t}`,missing_metadata:u}}:{field:{name:i,fdId:s,fdType:o,metaType:a}}}function Yi(e,t,n){if(n){let i=e.find(s=>S(s.fd_id)===n||S(s.id)===n);if(i)return i}let r=t.trim();return e.find(i=>[i.fd_id,i.id,i.name,i.alias].map(S).includes(r))}function Wi(e){let t=I(e.content),n=[],r=I(I(t.source).field);Object.keys(r).length&&n.push(Ht(r));let i=I(I(t.meta).chartMain),s=I(i.zoneData);for(let[o,a]of Object.entries(s))n.push(...re(a).map(u=>Ht(u,o)));return Xi(n)}function Ht(e,t){return _({name:j(e.name,e.title,e.originTitle,e.alias),alias:j(e.alias,e.title),id:S(e.id),fd_id:j(e.fdId,e.fd_id,e.id),fd_type:j(e.fdType,e.fd_type),meta_type:j(e.metaType,e.meta_type),zone_id:j(e.zoneId,e.zone_id,t)})}function Xi(e){let t=new Set;return e.filter(n=>{let r=j(n.fd_id,n.id,n.name,n.alias);return!r||t.has(r)?!1:(t.add(r),!0)})}function Zi(e,t,n){if(e==="SELECTOR"||e==="TREE_SELECTOR")return Je(t.exceedLimit)?!0:Jt(t,n);let r=I(t.chartMain);return Je(r.hasMoreData)?!0:Jt(r,n)}function Jt(e,t){let n=$e(e.count),r=$e(e.limit);return n!==void 0&&r!==void 0&&r>0?n>r:n!==void 0&&n>t}function He(e){return j(e.alias,e.title,e.originTitle,e.name,e.fdId,e.id)??""}function Yt(e){let t=I(e);return Object.keys(t).length?j(t.title,t.name,t.originTitle,t.alias,t.v,t.value)??"":S(e)}function $t(e){let t=I(e);return Object.keys(t).length?"v"in t?t.v:"value"in t?t.value:Yt(e):e}function es(e,t){let n=t instanceof Error?t.message:String(t),r=n.match(/BI 请求失败:(?<method>[A-Z]+) (?<path>\S+) HTTP (?<status>\d+)/);return _({operation:e,path:r?.groups?.path,status:r?.groups?.status?Number(r.groups.status):void 0,message:n})}function re(e){return Array.isArray(e)?e.map(I).filter(t=>Object.keys(t).length):[]}function k(e){return Array.isArray(e)?e:[]}function ts(e){return JSON.parse(JSON.stringify(e))}function I(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function S(e){return typeof e=="string"?e:e==null?"":String(e)}function j(...e){return e.map(S).find(t=>t.trim())?.trim()}function Je(e){return typeof e=="boolean"?e:void 0}function $e(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Wt(e,t){return t?.length?e.map(n=>Object.fromEntries(t.map(r=>[r,n[r]]))):e}function Xt(e){return[...new Set(e.flatMap(t=>Object.keys(t)))]}function ns(e){let t=new Map;return e.map((n,r)=>{let i=n||`column_${r+1}`,s=t.get(i)??0;return t.set(i,s+1),s?`${i}_${s+1}`:i})}import{createHash as rs}from"crypto";import{z as f}from"zod";var is=6e4,$=1e4,Zt=10*6e4,Ie=new Map,be=new Map,Fe=new Map,Ve=new Map,tn=f.object({format:f.literal("markdown").describe("\u6700\u7EC8\u7ED3\u679C\u683C\u5F0F\u3002"),content:f.string().describe("\u6700\u7EC8\u5C55\u793A\u7ED9\u8C03\u7528\u8005\u6216\u7528\u6237\u7684 markdown \u5185\u5BB9\u3002")}),nn={themes:f.array(f.object({theme_id:f.string().optional(),theme_name:f.string().optional(),is_insight_enabled:f.boolean().optional()}).passthrough()),resolved_base_url:f.string().optional(),tried_base_urls:f.array(f.string()).optional()},rn={session_id:f.string().optional(),message_id:f.string().optional(),answer:f.unknown().optional().describe("ChatBI \u540E\u7AEF\u8FD4\u56DE\u7684\u95EE\u6570\u89E3\u91CA\u6216\u539F\u59CB\u7B54\u6848\u7ED3\u6784\u3002"),sql:f.unknown().optional().describe("ChatBI \u540E\u7AEF\u751F\u6210\u7684 SQL \u4FE1\u606F\u3002"),answer_status:f.string().optional(),final_status:f.string().optional(),query_result:f.unknown().optional().describe("ChatBI \u540E\u7AEF\u8FD4\u56DE\u7684\u7ED3\u6784\u5316\u67E5\u8BE2\u7ED3\u679C\uFF0C\u901A\u5E38\u5305\u542B columns\u3001preview\u3001truncated\u3001row_limit\u3002"),resolved_base_url:f.string().optional(),tried_base_urls:f.array(f.string()).optional()},ia={message_id:f.string().optional(),session_id:f.string().optional(),status:f.string(),detail:f.string().nullable().optional(),question:f.string().nullable().optional(),answer:f.unknown().optional(),final_result:tn.describe("\u6700\u7EC8\u5C55\u793A\u7ED3\u679C\uFF1B\u8C03\u7528\u65B9\u5E94\u4F18\u5148\u8BFB\u53D6 final_result.content\uFF0Canswer \u4EC5\u4FDD\u7559\u540E\u7AEF\u539F\u59CB\u7ED3\u679C\u3002"),resolved_base_url:f.string().optional(),tried_base_urls:f.array(f.string()).optional()},sn={theme_id:f.string().optional(),message_id:f.string().optional(),session_id:f.string().optional(),status:f.literal("started"),deduped:f.boolean(),retry_after_ms:f.number().int().nonnegative(),next_action:f.string().optional(),resolved_base_url:f.string().optional(),tried_base_urls:f.array(f.string()).optional()},on={message_id:f.string().optional(),session_id:f.string().optional(),status:f.string(),detail:f.string().nullable().optional(),question:f.string().nullable().optional(),answer:f.unknown().optional(),throttled:f.boolean(),retry_after_ms:f.number().int().nonnegative(),final_result:tn.describe("\u6700\u7EC8\u5C55\u793A\u7ED3\u679C\uFF1B\u4EC5\u5728 status \u4E3A success \u65F6\u5B58\u5728\u3002\u8C03\u7528\u65B9\u5E94\u4F18\u5148\u8BFB\u53D6 final_result.content\uFF0Canswer \u4EC5\u4FDD\u7559\u540E\u7AEF\u539F\u59CB\u7ED3\u679C\u3002").optional(),next_action:f.string().optional(),resolved_base_url:f.string().optional(),tried_base_urls:f.array(f.string()).optional()},an={is_insight:f.boolean().optional().describe("\u662F\u5426\u53EA\u5217\u51FA\u6D1E\u5BDF\u4E3B\u9898\u3002")},un={theme_id:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898 ID\u3002"),theme_name:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898\u540D\u79F0\u3002"),message:f.string().min(1).describe("\u81EA\u7136\u8BED\u8A00\u95EE\u6570\u95EE\u9898\u3002"),session_id:f.string().min(1).optional().describe("\u53EF\u9009\u4F1A\u8BDD ID\uFF0C\u7528\u4E8E\u95EE\u6570\u7EED\u95EE\u3002\u540C\u4E00\u4E2A session_id \u53EA\u80FD\u7EE7\u7EED\u95EE\u6570\uFF0C\u4E0D\u80FD\u518D\u7528\u4E8E\u6D1E\u5BDF\u3002"),external_context:f.string().min(1).optional().describe("\u53EF\u9009\u5916\u90E8\u4E0A\u4E0B\u6587\u3002")},sa={theme_id:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898 ID\u3002"),theme_name:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898\u540D\u79F0\u3002"),message:f.string().min(1).describe("\u81EA\u7136\u8BED\u8A00\u6D1E\u5BDF\u95EE\u9898\u3002"),session_id:f.string().min(1).optional().describe("\u53EF\u9009\u4F1A\u8BDD ID\uFF0C\u7528\u4E8E\u6D1E\u5BDF\u7EED\u95EE\u3002\u540C\u4E00\u4E2A session_id \u53EA\u80FD\u7EE7\u7EED\u6D1E\u5BDF\uFF0C\u4E0D\u80FD\u518D\u7528\u4E8E\u95EE\u6570\u3002"),external_context:f.string().min(1).optional().describe("\u53EF\u9009\u5916\u90E8\u4E0A\u4E0B\u6587\u3002"),timeout_ms:f.number().int().positive().optional().describe("\u7B49\u5F85\u6D1E\u5BDF\u5B8C\u6210\u7684\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA4 300000ms\u3002"),poll_interval_ms:f.number().int().positive().optional().describe("\u8F6E\u8BE2\u95F4\u9694\uFF0C\u9ED8\u8BA4 2000ms\u3002")},cn={theme_id:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898 ID\u3002"),theme_name:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898\u540D\u79F0\u3002"),message:f.string().min(1).describe("\u81EA\u7136\u8BED\u8A00\u6D1E\u5BDF\u95EE\u9898\u3002\u6D1E\u5BDF\u901A\u5E38\u8017\u65F6 2-3 \u5206\u949F\uFF0C5 \u5206\u949F\u89C6\u4E3A\u8D85\u65F6\uFF1B\u540C\u4E00\u95EE\u9898\u53EA\u53D1\u8D77\u4E00\u6B21\u3002"),session_id:f.string().min(1).optional().describe("\u53EF\u9009\u4F1A\u8BDD ID\uFF0C\u7528\u4E8E\u6D1E\u5BDF\u7EED\u95EE\u3002\u540C\u4E00\u4E2A session_id \u53EA\u80FD\u7EE7\u7EED\u6D1E\u5BDF\uFF0C\u4E0D\u80FD\u518D\u7528\u4E8E\u95EE\u6570\u3002"),external_context:f.string().min(1).optional().describe("\u53EF\u9009\u5916\u90E8\u4E0A\u4E0B\u6587\u3002")},dn={theme_id:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898 ID\u3002\u4F18\u5148\u4F7F\u7528 chatbi_insight_start \u8FD4\u56DE\u7684 theme_id\u3002"),theme_name:f.string().min(1).optional().describe("ChatBI \u4E3B\u9898\u540D\u79F0\uFF1B\u672A\u63D0\u4F9B theme_id \u65F6\u4F1A\u6309\u540D\u79F0\u67E5\u627E\u6D1E\u5BDF\u4E3B\u9898\u3002"),message_id:f.string().min(1).describe("chatbi_insight_start \u8FD4\u56DE\u7684\u6D88\u606F ID\u3002\u5EFA\u8BAE\u81F3\u5C11\u95F4\u9694 10 \u79D2\u67E5\u8BE2\u4E00\u6B21\uFF0C5 \u5206\u949F\u540E\u505C\u6B62\u7B49\u5F85\u3002")};async function ln(e,t){let n=new v(e);try{let r=await n.listThemes({isInsight:t.is_insight});return C({themes:r,resolved_base_url:n.getResolvedBaseUrl(),tried_base_urls:n.getTriedBaseUrls()})}catch(r){return Te(n,r,"listThemes")}}async function pn(e,t){let n=new v(e);try{let r=await n.query({themeId:t.theme_id,themeName:t.theme_name,message:t.message,sessionId:t.session_id,externalContext:t.external_context,fastMode:!0});return C({session_id:r.session_id,message_id:r.message_id,answer:r.answer,sql:r.sql,answer_status:r.answer_status,final_status:r.final_status,query_result:r.query_result,resolved_base_url:n.getResolvedBaseUrl(),tried_base_urls:n.getTriedBaseUrls()})}catch(r){return Te(n,r,"query")}}async function mn(e,t){let n=new v(e);try{let r=gn({caller_scope:hn(e),theme_id:t.theme_id,theme_name:t.theme_name,message:t.message,session_id:t.session_id,external_context:t.external_context}),i=ss(r);if(i)return C({...i,deduped:!0,retry_after_ms:$,next_action:"\u540C\u4E00\u6D1E\u5BDF\u95EE\u9898\u521A\u521A\u5DF2\u7ECF\u53D1\u8D77\uFF0C\u5DF2\u590D\u7528\u5DF2\u6709 message_id\u3002\u8BF7\u4F7F\u7528 chatbi_insight_poll \u67E5\u8BE2\u7ED3\u679C\u3002"});let s=Fe.get(r);if(s){let u=await s;return C({...u,deduped:!0,retry_after_ms:$,next_action:"\u540C\u4E00\u6D1E\u5BDF\u95EE\u9898\u6B63\u5728\u53D1\u8D77\u4E2D\uFF0C\u5DF2\u590D\u7528\u5DF2\u6709\u8BF7\u6C42\u7ED3\u679C\u3002\u8BF7\u4F7F\u7528 chatbi_insight_poll \u67E5\u8BE2\u7ED3\u679C\u3002"})}let o=n.startInsight({themeId:t.theme_id,themeName:t.theme_name,message:t.message,sessionId:t.session_id,externalContext:t.external_context}).then(u=>{let c={theme_id:u.theme_id,message_id:u.message_id,session_id:u.session_id,status:"started"};return os(r,c),c}).finally(()=>{Fe.delete(r)});Fe.set(r,o);let a=await o;return C({...a,deduped:!1,retry_after_ms:$,next_action:"\u6D1E\u5BDF\u4EFB\u52A1\u5DF2\u53D1\u8D77\u3002\u6D1E\u5BDF\u901A\u5E38\u8017\u65F6 2-3 \u5206\u949F\uFF0C\u8BF7\u4F7F\u7528 chatbi_insight_poll \u643A\u5E26 theme_id \u548C message_id \u67E5\u8BE2\u7ED3\u679C\uFF1B5 \u5206\u949F\u540E\u4ECD\u672A\u6210\u529F\u53EF\u89C6\u4E3A\u8D85\u65F6\u3002",resolved_base_url:n.getResolvedBaseUrl(),tried_base_urls:n.getTriedBaseUrls()})}catch(r){return Te(n,r,"insight.start")}}async function fn(e,t){let n=new v(e);try{let r=gn({caller_scope:hn(e),message_id:t.message_id}),i=as(r);if(i){let p=ze(i.result),g=Ke(i.result,!0);return C({message_id:i.result.message_id,session_id:i.result.session_id,status:i.result.status,detail:Qe(i.result),question:i.result.question,answer:i.result.answer,throttled:!0,retry_after_ms:i.retryAfterMs,...p,next_action:g})}let s=Ve.get(r);if(s){let p=await s,g=Ye(p.status),b=ze(p),y=Ke(p,!0);return C({message_id:p.message_id,session_id:p.session_id,status:p.status,detail:Qe(p),question:p.question,answer:p.answer,throttled:!0,retry_after_ms:g?0:$,...b,next_action:y})}let o=n.pollInsight({themeId:t.theme_id,themeName:t.theme_name,messageId:t.message_id}).then(p=>(us(r,p),p)).finally(()=>{Ve.delete(r)});Ve.set(r,o);let a=await o,u=Ye(a.status),c=ze(a),d=Ke(a,!1);return C({message_id:a.message_id,session_id:a.session_id,status:a.status,detail:Qe(a),question:a.question,answer:a.answer,throttled:!1,retry_after_ms:u?0:$,...c,next_action:d,resolved_base_url:n.getResolvedBaseUrl(),tried_base_urls:n.getTriedBaseUrls()})}catch(r){return Te(n,r,"insight.poll")}}function ze(e){return e.status!=="success"?{}:{final_result:{format:"markdown",content:_n(e)}}}function Qe(e){return e.detail!=null?e.detail:e.status==="failure"||e.status==="stopped"?cs(e):e.detail}function Ke(e,t){if(e.status!=="success")return e.status==="waiting"?t?"\u540C\u4E00 message_id \u6B63\u5728\u67E5\u8BE2\u4E2D\u6216\u521A\u521A\u67E5\u8BE2\u8FC7\uFF0C\u5DF2\u8FD4\u56DE\u5DF2\u6709\u7ED3\u679C\uFF1B\u8BF7\u81F3\u5C11\u95F4\u9694 10 \u79D2\u518D\u67E5\u3002":"\u6D1E\u5BDF\u4EFB\u52A1\u4ECD\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u7EE7\u7EED\u8C03\u7528 chatbi_insight_poll \u67E5\u8BE2\u7ED3\u679C\u3002":e.status==="failure"||e.status==="stopped"?"\u6D1E\u5BDF\u4EFB\u52A1\u672A\u6210\u529F\u5B8C\u6210\uFF0C\u8BF7\u67E5\u770B detail\uFF1B\u5982\u9700\u91CD\u8BD5\u8BF7\u91CD\u65B0\u8C03\u7528 chatbi_insight_start\u3002":"\u6D1E\u5BDF\u4EFB\u52A1\u5904\u4E8E\u975E\u6210\u529F\u72B6\u6001\uFF0C\u8BF7\u67E5\u770B status \u548C detail \u540E\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\u67E5\u8BE2\u3002"}function ss(e){ye();let t=Ie.get(e);if(!(!t||Date.now()-t.createdAt>=is))return t.result}function os(e,t){ye(),Ie.set(e,{createdAt:Date.now(),result:t})}function as(e){ye();let t=be.get(e);if(!t)return;let n=Date.now()-t.checkedAt,r=Ye(t.result.status);if(!(!r&&n>=$))return{result:t.result,retryAfterMs:r?0:Math.max(0,$-n)}}function Ye(e){return e==="success"||e==="failure"||e==="stopped"}function us(e,t){ye(),be.set(e,{checkedAt:Date.now(),result:t})}function ye(){let e=Date.now();for(let[t,n]of Ie)e-n.createdAt>=Zt&&Ie.delete(t);for(let[t,n]of be)e-n.checkedAt>=Zt&&be.delete(t)}function gn(e){return JSON.stringify(Object.keys(e).sort().reduce((t,n)=>{let r=e[n];return typeof r<"u"&&(t[n]=r),t},{}))}function hn(e){return e.BI_UID_TOKEN?`uid:${en(e.BI_UID_TOKEN)}`:`login:${en(`${e.BI_LOGIN_DOMAIN??""}\0${e.BI_LOGIN_ID??""}`)}`}function en(e){return rs("sha256").update(e).digest("hex").slice(0,16)}function _n(e){let t=e.answer?.trim();if(t)return fs(t);let n=e.detail?.trim();return n||"\u5206\u6790\u5DF2\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u53EF\u5C55\u793A\u7684 markdown \u5185\u5BB9\u3002"}function cs(e){switch(e.status){case"success":return _n(e);case"waiting":return"\u6D1E\u5BDF\u4EFB\u52A1\u4ECD\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u7EE7\u7EED\u8C03\u7528 chatbi_insight_poll \u67E5\u8BE2\u7ED3\u679C\u3002";case"failure":case"stopped":return e.detail?.trim()||"\u6D1E\u5BDF\u4EFB\u52A1\u672A\u6210\u529F\u5B8C\u6210\u3002";default:return e.detail?.trim()||`\u6D1E\u5BDF\u4EFB\u52A1\u5F53\u524D\u72B6\u6001\uFF1A${e.status}`}}function ds(e,t){let n=[`| ${e.join(" | ")} |`,`|${e.map(()=>" --- ").join("|")}|`];for(let r of t)n.push(`| ${e.map((i,s)=>ps(ls(r[s]))).join(" | ")} |`);return n.join(`
|