refactor: update references from CSAgent to AgentDesk across the codebase

This commit is contained in:
mlogclub
2026-05-31 18:48:49 +08:00
parent eb04c344a5
commit c1e972001d
7 changed files with 58 additions and 58 deletions
@@ -740,7 +740,7 @@ function WebAccessGuide({ channelId }: { channelId: string }) {
return "" return ""
} }
return `<script> return `<script>
window.CSAgentConfig = { window.AgentDeskConfig = {
channelId: "${channelId}" channelId: "${channelId}"
}; };
</script> </script>
+16 -16
View File
@@ -4,12 +4,12 @@ import { SignJWT } from "jose"
import { CheckIcon, CopyIcon } from "lucide-react" import { CheckIcon, CopyIcon } from "lucide-react"
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
import type { CSAgentConfig } from "@/lib/sdk/config-types" import type { AgentDeskConfig } from "@/lib/sdk/config-types"
import { useI18n } from "@/i18n/provider" import { useI18n } from "@/i18n/provider"
const STORAGE_KEY = "agent-desk-web-widget-test-config" const STORAGE_KEY = "agent-desk-web-widget-test-config"
const DEFAULT_JWT_TTL_MINUTES = "30" const DEFAULT_JWT_TTL_MINUTES = "30"
const INITIAL_CONFIG: CSAgentConfig = { const INITIAL_CONFIG: AgentDeskConfig = {
channelId: "", channelId: "",
baseUrl: "", baseUrl: "",
apiBaseUrl: "", apiBaseUrl: "",
@@ -17,7 +17,7 @@ const INITIAL_CONFIG: CSAgentConfig = {
type AuthMode = "guest" | "jwt" type AuthMode = "guest" | "jwt"
type WidgetDemoConfig = CSAgentConfig & { type WidgetDemoConfig = AgentDeskConfig & {
authMode?: AuthMode authMode?: AuthMode
jwtSecret?: string jwtSecret?: string
jwtUserId?: string jwtUserId?: string
@@ -53,32 +53,32 @@ function removeMountedWidget() {
return return
} }
window.CSAgentWidget?.destroy() window.AgentDeskWidget?.destroy()
document document
.querySelectorAll( .querySelectorAll(
'[data-agent-desk-widget="launcher"], [data-agent-desk-widget="frame"], [data-agent-desk-widget="script"]' '[data-agent-desk-widget="launcher"], [data-agent-desk-widget="frame"], [data-agent-desk-widget="script"]'
) )
.forEach((node) => node.remove()) .forEach((node) => node.remove())
delete window.CSAgentConfig delete window.AgentDeskConfig
delete window.__CS_AI_AGENT_WIDGET_CONFIG__ delete window.__CS_AI_AGENT_WIDGET_CONFIG__
delete window.__CS_AI_AGENT_WIDGET_STATE__ delete window.__CS_AI_AGENT_WIDGET_STATE__
delete window.CSAgentWidget delete window.AgentDeskWidget
} }
function injectWidget(config: CSAgentConfig) { function injectWidget(config: AgentDeskConfig) {
removeMountedWidget() removeMountedWidget()
window.CSAgentConfig = config window.AgentDeskConfig = config
const script = document.createElement("script") const script = document.createElement("script")
script.async = true script.async = true
script.src = `${window.location.origin}/sdk/agent-desk-sdk.min.js` script.src = `${window.location.origin}/sdk/agent-desk-sdk.min.js`
script.dataset.csAgentWidget = "script" script.dataset.agentDeskWidget = "script"
document.body.appendChild(script) document.body.appendChild(script)
} }
function buildWidgetConfig(config: WidgetDemoConfig): CSAgentConfig { function buildWidgetConfig(config: WidgetDemoConfig): AgentDeskConfig {
const nextConfig: CSAgentConfig = { const nextConfig: AgentDeskConfig = {
channelId: config.channelId.trim(), channelId: config.channelId.trim(),
baseUrl: "", baseUrl: "",
apiBaseUrl: "", apiBaseUrl: "",
@@ -200,7 +200,7 @@ export function SupportWidgetDemo() {
} }
return `<script> return `<script>
window.CSAgentConfig = { window.AgentDeskConfig = {
${configLines.join(",\n")} ${configLines.join(",\n")}
}; };
</script> </script>
@@ -225,11 +225,11 @@ ${configLines.join(",\n")}
} }
async function handleCopyDirectUrl() { async function handleCopyDirectUrl() {
if (!window.CSAgentWidget || typeof navigator === "undefined") { if (!window.AgentDeskWidget || typeof navigator === "undefined") {
return return
} }
try { try {
const url = await window.CSAgentWidget.getChatUrl() const url = await window.AgentDeskWidget.getChatUrl()
setLatestDirectChatUrl(url) setLatestDirectChatUrl(url)
if (config.authMode === "jwt") { if (config.authMode === "jwt") {
setGeneratedToken(new URL(url).searchParams.get("userToken") || "") setGeneratedToken(new URL(url).searchParams.get("userToken") || "")
@@ -243,11 +243,11 @@ ${configLines.join(",\n")}
} }
async function handleOpenDirectChat() { async function handleOpenDirectChat() {
if (!window.CSAgentWidget) { if (!window.AgentDeskWidget) {
return return
} }
try { try {
const url = await window.CSAgentWidget.getChatUrl() const url = await window.AgentDeskWidget.getChatUrl()
setLatestDirectChatUrl(url) setLatestDirectChatUrl(url)
if (config.authMode === "jwt") { if (config.authMode === "jwt") {
setGeneratedToken(new URL(url).searchParams.get("userToken") || "") setGeneratedToken(new URL(url).searchParams.get("userToken") || "")
+8 -8
View File
@@ -68,7 +68,7 @@ async function loadSdk(config) {
createElementNS: (_namespace, tagName) => createElement(tagName), createElementNS: (_namespace, tagName) => createElement(tagName),
}, },
window: { window: {
CSAgentConfig: config, AgentDeskConfig: config,
location: { location: {
origin: "https://host.example", origin: "https://host.example",
}, },
@@ -109,10 +109,10 @@ test("getChatUrl resolves a fresh userToken for each call", async () => {
getUserToken: async () => `token_${++calls}`, getUserToken: async () => `token_${++calls}`,
}) })
assert.equal(typeof sandbox.window.CSAgentWidget.getChatUrl, "function") assert.equal(typeof sandbox.window.AgentDeskWidget.getChatUrl, "function")
const first = await sandbox.window.CSAgentWidget.getChatUrl() const first = await sandbox.window.AgentDeskWidget.getChatUrl()
const second = await sandbox.window.CSAgentWidget.getChatUrl() const second = await sandbox.window.AgentDeskWidget.getChatUrl()
assert.equal(new URL(first).pathname, "/support/chat/") assert.equal(new URL(first).pathname, "/support/chat/")
assert.equal(new URL(second).pathname, "/support/chat/") assert.equal(new URL(second).pathname, "/support/chat/")
@@ -129,7 +129,7 @@ test("launcher click creates chat iframe with a freshly resolved userToken", asy
}) })
await flushPromises() await flushPromises()
const launcher = sandbox.document.body.children.find( const launcher = sandbox.document.body.children.find(
(child) => child.dataset.csAgentWidget === "launcher" (child) => child.dataset.agentDeskWidget === "launcher"
) )
assert.ok(launcher) assert.ok(launcher)
@@ -138,7 +138,7 @@ test("launcher click creates chat iframe with a freshly resolved userToken", asy
await flushPromises() await flushPromises()
const frame = sandbox.document.body.children.find( const frame = sandbox.document.body.children.find(
(child) => child.dataset.csAgentWidget === "frame" (child) => child.dataset.agentDeskWidget === "frame"
) )
assert.ok(frame) assert.ok(frame)
@@ -153,14 +153,14 @@ test("chat iframe layout uses dynamic viewport height for iOS browser chrome", a
}) })
await flushPromises() await flushPromises()
const launcher = sandbox.document.body.children.find( const launcher = sandbox.document.body.children.find(
(child) => child.dataset.csAgentWidget === "launcher" (child) => child.dataset.agentDeskWidget === "launcher"
) )
launcher.click() launcher.click()
await flushPromises() await flushPromises()
const frame = sandbox.document.body.children.find( const frame = sandbox.document.body.children.find(
(child) => child.dataset.csAgentWidget === "frame" (child) => child.dataset.agentDeskWidget === "frame"
) )
assert.ok(frame) assert.ok(frame)
+23 -23
View File
@@ -1,10 +1,10 @@
import type { import type {
CSAgentConfig, AgentDeskConfig,
CSAgentWidget, AgentDeskWidget,
SupportChatRuntimeConfig, SupportChatRuntimeConfig,
} from "./config-types" } from "./config-types"
type NormalizedCSAgentConfig = CSAgentConfig & { type NormalizedAgentDeskConfig = AgentDeskConfig & {
baseUrl: string baseUrl: string
channelId: string channelId: string
position: "left" | "right" position: "left" | "right"
@@ -23,7 +23,7 @@ type WidgetState = {
configLoading: boolean configLoading: boolean
frameHideTimer: number | null frameHideTimer: number | null
frameDestroyTimer: number | null frameDestroyTimer: number | null
config: NormalizedCSAgentConfig | null config: NormalizedAgentDeskConfig | null
frameConfig: SupportChatRuntimeConfig | null frameConfig: SupportChatRuntimeConfig | null
frameUrl: URL | null frameUrl: URL | null
animationDuration: number animationDuration: number
@@ -33,7 +33,7 @@ type WidgetState = {
type WidgetConfigResponse = { type WidgetConfigResponse = {
success?: boolean success?: boolean
data?: Partial<Pick< data?: Partial<Pick<
CSAgentConfig, AgentDeskConfig,
"title" | "subtitle" | "themeColor" | "position" | "width" "title" | "subtitle" | "themeColor" | "position" | "width"
>> >>
} }
@@ -64,7 +64,7 @@ type FrameMessage =
(function () { (function () {
const DEFAULT_CONFIG: Pick< const DEFAULT_CONFIG: Pick<
NormalizedCSAgentConfig, NormalizedAgentDeskConfig,
"position" | "themeColor" | "width" "position" | "themeColor" | "width"
> = { > = {
position: "right", position: "right",
@@ -94,7 +94,7 @@ type FrameMessage =
window.__CS_AI_AGENT_WIDGET_STATE__ = state window.__CS_AI_AGENT_WIDGET_STATE__ = state
} }
function normalizeConfig(config?: CSAgentConfig): NormalizedCSAgentConfig { function normalizeConfig(config?: AgentDeskConfig): NormalizedAgentDeskConfig {
const merged: Record<string, unknown> = { ...DEFAULT_CONFIG, ...(config || {}) } const merged: Record<string, unknown> = { ...DEFAULT_CONFIG, ...(config || {}) }
merged.baseUrl = String(merged.baseUrl || window.location.origin).replace(/\/$/, "") merged.baseUrl = String(merged.baseUrl || window.location.origin).replace(/\/$/, "")
if (merged.apiBaseUrl) { if (merged.apiBaseUrl) {
@@ -109,10 +109,10 @@ type FrameMessage =
if (typeof merged.getUserToken !== "function") { if (typeof merged.getUserToken !== "function") {
delete merged.getUserToken delete merged.getUserToken
} }
return merged as NormalizedCSAgentConfig return merged as NormalizedAgentDeskConfig
} }
function resolveWidgetBaseUrl(config: NormalizedCSAgentConfig) { function resolveWidgetBaseUrl(config: NormalizedAgentDeskConfig) {
const currentScript = document.currentScript as HTMLScriptElement | null const currentScript = document.currentScript as HTMLScriptElement | null
if (currentScript?.src) { if (currentScript?.src) {
return currentScript.src.replace(/\/sdk\/agent-desk-sdk\.min\.js(?:\?.*)?$/, "") return currentScript.src.replace(/\/sdk\/agent-desk-sdk\.min\.js(?:\?.*)?$/, "")
@@ -120,7 +120,7 @@ type FrameMessage =
return String(config.widgetBaseUrl || config.baseUrl || window.location.origin).replace(/\/$/, "") return String(config.widgetBaseUrl || config.baseUrl || window.location.origin).replace(/\/$/, "")
} }
function createFrameUrl(config: NormalizedCSAgentConfig, userToken: string) { function createFrameUrl(config: NormalizedAgentDeskConfig, userToken: string) {
const widgetBaseUrl = resolveWidgetBaseUrl(config) const widgetBaseUrl = resolveWidgetBaseUrl(config)
const frameUrl = new URL(`${widgetBaseUrl}/support/chat/`) const frameUrl = new URL(`${widgetBaseUrl}/support/chat/`)
frameUrl.searchParams.set("channelId", config.channelId) frameUrl.searchParams.set("channelId", config.channelId)
@@ -133,7 +133,7 @@ type FrameMessage =
} }
function createFrameConfig( function createFrameConfig(
config: NormalizedCSAgentConfig, config: NormalizedAgentDeskConfig,
userToken: string userToken: string
): SupportChatRuntimeConfig { ): SupportChatRuntimeConfig {
const { getUserToken: _getUserToken, ...payload } = config const { getUserToken: _getUserToken, ...payload } = config
@@ -169,13 +169,13 @@ type FrameMessage =
} }
function mergeWidgetConfig( function mergeWidgetConfig(
config: NormalizedCSAgentConfig, config: NormalizedAgentDeskConfig,
remoteConfig?: WidgetConfigResponse["data"] remoteConfig?: WidgetConfigResponse["data"]
) { ) {
if (!remoteConfig) { if (!remoteConfig) {
return config return config
} }
const merged: NormalizedCSAgentConfig = { ...config } const merged: NormalizedAgentDeskConfig = { ...config }
const remoteKeys = ["title", "subtitle", "themeColor", "position", "width"] as const const remoteKeys = ["title", "subtitle", "themeColor", "position", "width"] as const
remoteKeys.forEach((key) => { remoteKeys.forEach((key) => {
const value = remoteConfig[key] const value = remoteConfig[key]
@@ -186,7 +186,7 @@ type FrameMessage =
return merged return merged
} }
function fetchWidgetConfig(config: NormalizedCSAgentConfig) { function fetchWidgetConfig(config: NormalizedAgentDeskConfig) {
const baseUrl = String(config.apiBaseUrl || config.baseUrl || "").replace(/\/$/, "") const baseUrl = String(config.apiBaseUrl || config.baseUrl || "").replace(/\/$/, "")
if (!baseUrl || !config.channelId || typeof fetch !== "function") { if (!baseUrl || !config.channelId || typeof fetch !== "function") {
return Promise.resolve(config) return Promise.resolve(config)
@@ -368,7 +368,7 @@ type FrameMessage =
} }
state.frame = document.createElement("iframe") state.frame = document.createElement("iframe")
state.frame.dataset.csAgentWidget = "frame" state.frame.dataset.agentDeskWidget = "frame"
state.frame.title = state.config.title || getDefaultWidgetTitle() state.frame.title = state.config.title || getDefaultWidgetTitle()
state.frame.src = state.frameUrl.toString() state.frame.src = state.frameUrl.toString()
applyFrameLayout() applyFrameLayout()
@@ -434,7 +434,7 @@ type FrameMessage =
] ]
const text = document.createElement("span") const text = document.createElement("span")
button.type = "button" button.type = "button"
button.dataset.csAgentWidget = "launcher" button.dataset.agentDeskWidget = "launcher"
button.setAttribute("aria-label", config.title || getDefaultWidgetTitle()) button.setAttribute("aria-label", config.title || getDefaultWidgetTitle())
icon.setAttribute("viewBox", "0 0 24 24") icon.setAttribute("viewBox", "0 0 24 24")
icon.setAttribute("fill", "none") icon.setAttribute("fill", "none")
@@ -491,8 +491,8 @@ type FrameMessage =
return button return button
} }
function mount(config?: CSAgentConfig) { function mount(config?: AgentDeskConfig) {
const rawConfig = config || window.CSAgentConfig || { channelId: "" } const rawConfig = config || window.AgentDeskConfig || { channelId: "" }
state.config = normalizeConfig(rawConfig) state.config = normalizeConfig(rawConfig)
const widgetBaseUrl = resolveWidgetBaseUrl(state.config) const widgetBaseUrl = resolveWidgetBaseUrl(state.config)
if (!rawConfig.baseUrl) { if (!rawConfig.baseUrl) {
@@ -552,7 +552,7 @@ type FrameMessage =
}) })
} }
window.CSAgentWidget = { window.AgentDeskWidget = {
mount, mount,
destroy, destroy,
open: () => openWidget(), open: () => openWidget(),
@@ -562,21 +562,21 @@ type FrameMessage =
}, },
getChatUrl: () => { getChatUrl: () => {
if (!state.config) { if (!state.config) {
mount(window.CSAgentConfig || { channelId: "" }) mount(window.AgentDeskConfig || { channelId: "" })
} }
if (!state.config?.channelId) { if (!state.config?.channelId) {
return Promise.reject(new Error("channelId is required")) return Promise.reject(new Error("channelId is required"))
} }
return prepareFrameUrl().then((frameUrl) => frameUrl.toString()) return prepareFrameUrl().then((frameUrl) => frameUrl.toString())
}, },
} satisfies CSAgentWidget } satisfies AgentDeskWidget
if (!state.listenerBound) { if (!state.listenerBound) {
window.addEventListener("message", handleWindowMessage) window.addEventListener("message", handleWindowMessage)
state.listenerBound = true state.listenerBound = true
} }
if (window.CSAgentConfig) { if (window.AgentDeskConfig) {
mount(window.CSAgentConfig) mount(window.AgentDeskConfig)
} }
})() })()
+7 -7
View File
@@ -1,4 +1,4 @@
export type CSAgentConfig = { export type AgentDeskConfig = {
channelId: string channelId: string
baseUrl?: string baseUrl?: string
apiBaseUrl?: string apiBaseUrl?: string
@@ -16,13 +16,13 @@ export type CSAgentConfig = {
width?: string width?: string
} }
export type SupportChatRuntimeConfig = Omit<CSAgentConfig, "getUserToken"> & { export type SupportChatRuntimeConfig = Omit<AgentDeskConfig, "getUserToken"> & {
/** Used only by /support/chat to exchange for a chat token; not part of CSAgentConfig. */ /** Used only by /support/chat to exchange for a chat token; not part of AgentDeskConfig. */
userToken?: string userToken?: string
} }
export type CSAgentWidget = { export type AgentDeskWidget = {
mount: (config?: CSAgentConfig) => void mount: (config?: AgentDeskConfig) => void
destroy: () => void destroy: () => void
open: () => Promise<void> open: () => Promise<void>
close: () => void close: () => void
@@ -31,8 +31,8 @@ export type CSAgentWidget = {
declare global { declare global {
interface Window { interface Window {
CSAgentConfig?: CSAgentConfig AgentDeskConfig?: AgentDeskConfig
CSAgentWidget?: CSAgentWidget AgentDeskWidget?: AgentDeskWidget
__CS_AI_AGENT_WIDGET_CONFIG__?: SupportChatRuntimeConfig __CS_AI_AGENT_WIDGET_CONFIG__?: SupportChatRuntimeConfig
__CS_AI_AGENT_WIDGET_STATE__?: unknown __CS_AI_AGENT_WIDGET_STATE__?: unknown
} }
+2 -2
View File
@@ -36,8 +36,8 @@ export function readSupportChatRuntimeConfig(): SupportChatRuntimeConfig {
if (window.__CS_AI_AGENT_WIDGET_CONFIG__) { if (window.__CS_AI_AGENT_WIDGET_CONFIG__) {
return window.__CS_AI_AGENT_WIDGET_CONFIG__ return window.__CS_AI_AGENT_WIDGET_CONFIG__
} }
if (window.CSAgentConfig) { if (window.AgentDeskConfig) {
const { getUserToken: _getUserToken, ...hostConfig } = window.CSAgentConfig const { getUserToken: _getUserToken, ...hostConfig } = window.AgentDeskConfig
return { return {
...fallback, ...fallback,
...hostConfig, ...hostConfig,
File diff suppressed because one or more lines are too long