@salesforce/ui-bundle-template-feature-react-agentforce-conversation-client 11.50.0 → 11.51.0
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/dist/CHANGELOG.md +8 -0
- package/dist/force-app/main/default/uiBundles/feature-react-agentforce-conversation-client/package.json +4 -4
- package/dist/force-app/main/default/uiBundles/feature-react-agentforce-conversation-client/src/components/AgentforceConversationClient.tsx +16 -132
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +2 -2
- package/src/force-app/main/default/uiBundles/feature-react-agentforce-conversation-client/src/components/AgentforceConversationClient.tsx +16 -132
package/dist/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [11.51.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.50.0...v11.51.0) (2026-08-07)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [11.50.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.49.4...v11.50.0) (2026-08-07)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"graphql:schema": "node scripts/get-graphql-schema.mjs"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@salesforce/platform-sdk": "^11.
|
|
22
|
-
"@salesforce/ui-bundle": "^11.
|
|
21
|
+
"@salesforce/platform-sdk": "^11.51.0",
|
|
22
|
+
"@salesforce/ui-bundle": "^11.51.0",
|
|
23
23
|
"@tailwindcss/vite": "^4.1.17",
|
|
24
24
|
"class-variance-authority": "^0.7.1",
|
|
25
25
|
"clsx": "^2.1.1",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
|
46
46
|
"@graphql-tools/utils": "^11.0.0",
|
|
47
47
|
"@playwright/test": "^1.49.0",
|
|
48
|
-
"@salesforce/graphiti": "^11.
|
|
49
|
-
"@salesforce/vite-plugin-ui-bundle": "^11.
|
|
48
|
+
"@salesforce/graphiti": "^11.51.0",
|
|
49
|
+
"@salesforce/vite-plugin-ui-bundle": "^11.51.0",
|
|
50
50
|
"@testing-library/jest-dom": "^6.6.3",
|
|
51
51
|
"@testing-library/react": "^16.1.0",
|
|
52
52
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -6,59 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
import { embedAgentforceClient } from "@salesforce/agentforce-conversation-client";
|
|
8
8
|
import type { AgentforceClientConfig } from "@salesforce/agentforce-conversation-client";
|
|
9
|
+
import { createAccEmbedder } from "@salesforce/agentforce-conversation-client/ui-bundle";
|
|
9
10
|
import { useEffect, useMemo, useRef } from "react";
|
|
10
|
-
import type {
|
|
11
|
-
ResolvedEmbedOptions,
|
|
12
|
-
AgentforceConversationClientProps,
|
|
13
|
-
} from "../types/conversation";
|
|
11
|
+
import type { AgentforceConversationClientProps } from "../types/conversation";
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
initialized: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface WindowWithAgentforceSingleton extends Window {
|
|
24
|
-
[SINGLETON_KEY]?: AgentforceConversationClientSingleton;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type GlobalWithSfdcEnv = typeof globalThis & {
|
|
28
|
-
SFDC_ENV?: {
|
|
29
|
-
orgUrl?: string;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function getSingleton(): AgentforceConversationClientSingleton {
|
|
34
|
-
const win = window as WindowWithAgentforceSingleton;
|
|
35
|
-
if (!win[SINGLETON_KEY]) {
|
|
36
|
-
win[SINGLETON_KEY] = {
|
|
37
|
-
initialized: false,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
return win[SINGLETON_KEY]!;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getOrCreateGlobalHost(): HTMLDivElement {
|
|
44
|
-
let host = document.getElementById(GLOBAL_HOST_ID) as HTMLDivElement | null;
|
|
45
|
-
if (!host) {
|
|
46
|
-
host = document.createElement("div");
|
|
47
|
-
host.id = GLOBAL_HOST_ID;
|
|
48
|
-
document.body.appendChild(host);
|
|
49
|
-
}
|
|
50
|
-
return host;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getDefaultEmbedOptions(): ResolvedEmbedOptions {
|
|
54
|
-
const sfdcEnv = (globalThis as GlobalWithSfdcEnv).SFDC_ENV;
|
|
55
|
-
return { salesforceOrigin: sfdcEnv?.orgUrl };
|
|
56
|
-
}
|
|
13
|
+
// The embed orchestration (window singleton, global host, dev frontdoor fetch,
|
|
14
|
+
// SFDC_ENV default, partial-embed cleanup) lives in the shared, framework-agnostic
|
|
15
|
+
// @salesforce/agentforce-conversation-client/ui-bundle glue. We hand it the
|
|
16
|
+
// low-level embed function via dependency injection.
|
|
17
|
+
const embedder = createAccEmbedder<AgentforceClientConfig>(embedAgentforceClient);
|
|
57
18
|
|
|
58
19
|
/**
|
|
59
20
|
* React wrapper that embeds the Agentforce Conversation Client (copilot/agent UI)
|
|
60
21
|
* using Lightning Out. Requires a valid Salesforce session for the given org.
|
|
61
|
-
*
|
|
22
|
+
* Flat props are normalized into an `AgentforceClientConfig` and passed through
|
|
23
|
+
* to the shared embedder as-is.
|
|
62
24
|
*/
|
|
63
25
|
export function AgentforceConversationClient({
|
|
64
26
|
agentId,
|
|
@@ -109,96 +71,18 @@ export function AgentforceConversationClient({
|
|
|
109
71
|
const inline = normalizedAgentforceClientConfig?.renderingConfig?.mode === "inline";
|
|
110
72
|
|
|
111
73
|
useEffect(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const singleton = getSingleton();
|
|
120
|
-
if (singleton.initialized || singleton.initPromise) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (inline && !containerRef.current) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const initialize = (options: ResolvedEmbedOptions) => {
|
|
129
|
-
if (singleton.initialized) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const existingEmbed = document.querySelector('lightning-out-application[data-lo="acc"]');
|
|
133
|
-
if (existingEmbed) {
|
|
134
|
-
singleton.initialized = true;
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const host = inline ? containerRef.current! : getOrCreateGlobalHost();
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
embedAgentforceClient({
|
|
141
|
-
container: host,
|
|
142
|
-
salesforceOrigin: salesforceOrigin ?? options.salesforceOrigin,
|
|
143
|
-
frontdoorUrl: frontdoorUrl ?? options.frontdoorUrl,
|
|
144
|
-
agentforceClientConfig: normalizedAgentforceClientConfig,
|
|
145
|
-
onReady,
|
|
146
|
-
onError,
|
|
147
|
-
});
|
|
148
|
-
singleton.initialized = true;
|
|
149
|
-
} catch (err) {
|
|
150
|
-
// Strip a partially-created LO element so the next mount can retry.
|
|
151
|
-
const partialEmbed = document.querySelector('lightning-out-application[data-lo="acc"]');
|
|
152
|
-
partialEmbed?.remove();
|
|
153
|
-
console.error("AgentforceConversationClient: initialization failed", err);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const safeInitialize = (options: ResolvedEmbedOptions) => {
|
|
158
|
-
try {
|
|
159
|
-
initialize(options);
|
|
160
|
-
} catch (initErr) {
|
|
161
|
-
console.error("AgentforceConversationClient: initialization failed", initErr);
|
|
162
|
-
singleton.initialized = false;
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const shouldFetchFrontdoor = window.location.hostname === "localhost";
|
|
167
|
-
|
|
168
|
-
if (shouldFetchFrontdoor) {
|
|
169
|
-
singleton.initPromise = fetch("/__lo/frontdoor")
|
|
170
|
-
.then(async (res) => {
|
|
171
|
-
if (!res.ok) {
|
|
172
|
-
console.error("frontdoor fetch failed");
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const { frontdoorUrl: resolvedFrontdoorUrl } = await res.json();
|
|
176
|
-
safeInitialize({ frontdoorUrl: resolvedFrontdoorUrl });
|
|
177
|
-
})
|
|
178
|
-
.catch((err) => {
|
|
179
|
-
console.error("AgentforceConversationClient: failed to fetch frontdoor URL", err);
|
|
180
|
-
})
|
|
181
|
-
.finally(() => {
|
|
182
|
-
singleton.initPromise = undefined;
|
|
183
|
-
});
|
|
184
|
-
} else {
|
|
185
|
-
singleton.initPromise = Promise.resolve()
|
|
186
|
-
.then(() => {
|
|
187
|
-
safeInitialize(getDefaultEmbedOptions());
|
|
188
|
-
})
|
|
189
|
-
.catch((err) => {
|
|
190
|
-
console.error("AgentforceConversationClient: failed to embed Agentforce client", err);
|
|
191
|
-
})
|
|
192
|
-
.finally(() => {
|
|
193
|
-
singleton.initPromise = undefined;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
74
|
+
embedder.embedAcc(
|
|
75
|
+
normalizedAgentforceClientConfig,
|
|
76
|
+
{ salesforceOrigin, frontdoorUrl },
|
|
77
|
+
containerRef.current,
|
|
78
|
+
{ onReady, onError },
|
|
79
|
+
);
|
|
196
80
|
|
|
197
81
|
return () => {
|
|
198
82
|
// Intentionally no cleanup:
|
|
199
83
|
// This component guarantees a single LO initialization per window.
|
|
200
84
|
};
|
|
201
|
-
}, [salesforceOrigin, frontdoorUrl, normalizedAgentforceClientConfig,
|
|
85
|
+
}, [salesforceOrigin, frontdoorUrl, normalizedAgentforceClientConfig, onReady, onError]);
|
|
202
86
|
|
|
203
87
|
if (!inline) {
|
|
204
88
|
return null;
|
package/dist/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.51.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
9
|
-
"version": "11.
|
|
9
|
+
"version": "11.51.0",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"fast-xml-parser": "^5.9.3",
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/ui-bundle-template-feature-react-agentforce-conversation-client",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.51.0",
|
|
4
4
|
"description": "Embedded Agentforce conversation client feature for UI Bundles",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"author": "",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"clean": "rm -rf dist"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@salesforce/agentforce-conversation-client": "^11.
|
|
29
|
+
"@salesforce/agentforce-conversation-client": "^11.51.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/react": "^19.2.7",
|
|
@@ -6,59 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
import { embedAgentforceClient } from "@salesforce/agentforce-conversation-client";
|
|
8
8
|
import type { AgentforceClientConfig } from "@salesforce/agentforce-conversation-client";
|
|
9
|
+
import { createAccEmbedder } from "@salesforce/agentforce-conversation-client/ui-bundle";
|
|
9
10
|
import { useEffect, useMemo, useRef } from "react";
|
|
10
|
-
import type {
|
|
11
|
-
ResolvedEmbedOptions,
|
|
12
|
-
AgentforceConversationClientProps,
|
|
13
|
-
} from "../types/conversation";
|
|
11
|
+
import type { AgentforceConversationClientProps } from "../types/conversation";
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
initialized: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface WindowWithAgentforceSingleton extends Window {
|
|
24
|
-
[SINGLETON_KEY]?: AgentforceConversationClientSingleton;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type GlobalWithSfdcEnv = typeof globalThis & {
|
|
28
|
-
SFDC_ENV?: {
|
|
29
|
-
orgUrl?: string;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function getSingleton(): AgentforceConversationClientSingleton {
|
|
34
|
-
const win = window as WindowWithAgentforceSingleton;
|
|
35
|
-
if (!win[SINGLETON_KEY]) {
|
|
36
|
-
win[SINGLETON_KEY] = {
|
|
37
|
-
initialized: false,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
return win[SINGLETON_KEY]!;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getOrCreateGlobalHost(): HTMLDivElement {
|
|
44
|
-
let host = document.getElementById(GLOBAL_HOST_ID) as HTMLDivElement | null;
|
|
45
|
-
if (!host) {
|
|
46
|
-
host = document.createElement("div");
|
|
47
|
-
host.id = GLOBAL_HOST_ID;
|
|
48
|
-
document.body.appendChild(host);
|
|
49
|
-
}
|
|
50
|
-
return host;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getDefaultEmbedOptions(): ResolvedEmbedOptions {
|
|
54
|
-
const sfdcEnv = (globalThis as GlobalWithSfdcEnv).SFDC_ENV;
|
|
55
|
-
return { salesforceOrigin: sfdcEnv?.orgUrl };
|
|
56
|
-
}
|
|
13
|
+
// The embed orchestration (window singleton, global host, dev frontdoor fetch,
|
|
14
|
+
// SFDC_ENV default, partial-embed cleanup) lives in the shared, framework-agnostic
|
|
15
|
+
// @salesforce/agentforce-conversation-client/ui-bundle glue. We hand it the
|
|
16
|
+
// low-level embed function via dependency injection.
|
|
17
|
+
const embedder = createAccEmbedder<AgentforceClientConfig>(embedAgentforceClient);
|
|
57
18
|
|
|
58
19
|
/**
|
|
59
20
|
* React wrapper that embeds the Agentforce Conversation Client (copilot/agent UI)
|
|
60
21
|
* using Lightning Out. Requires a valid Salesforce session for the given org.
|
|
61
|
-
*
|
|
22
|
+
* Flat props are normalized into an `AgentforceClientConfig` and passed through
|
|
23
|
+
* to the shared embedder as-is.
|
|
62
24
|
*/
|
|
63
25
|
export function AgentforceConversationClient({
|
|
64
26
|
agentId,
|
|
@@ -109,96 +71,18 @@ export function AgentforceConversationClient({
|
|
|
109
71
|
const inline = normalizedAgentforceClientConfig?.renderingConfig?.mode === "inline";
|
|
110
72
|
|
|
111
73
|
useEffect(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const singleton = getSingleton();
|
|
120
|
-
if (singleton.initialized || singleton.initPromise) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (inline && !containerRef.current) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const initialize = (options: ResolvedEmbedOptions) => {
|
|
129
|
-
if (singleton.initialized) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const existingEmbed = document.querySelector('lightning-out-application[data-lo="acc"]');
|
|
133
|
-
if (existingEmbed) {
|
|
134
|
-
singleton.initialized = true;
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const host = inline ? containerRef.current! : getOrCreateGlobalHost();
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
embedAgentforceClient({
|
|
141
|
-
container: host,
|
|
142
|
-
salesforceOrigin: salesforceOrigin ?? options.salesforceOrigin,
|
|
143
|
-
frontdoorUrl: frontdoorUrl ?? options.frontdoorUrl,
|
|
144
|
-
agentforceClientConfig: normalizedAgentforceClientConfig,
|
|
145
|
-
onReady,
|
|
146
|
-
onError,
|
|
147
|
-
});
|
|
148
|
-
singleton.initialized = true;
|
|
149
|
-
} catch (err) {
|
|
150
|
-
// Strip a partially-created LO element so the next mount can retry.
|
|
151
|
-
const partialEmbed = document.querySelector('lightning-out-application[data-lo="acc"]');
|
|
152
|
-
partialEmbed?.remove();
|
|
153
|
-
console.error("AgentforceConversationClient: initialization failed", err);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const safeInitialize = (options: ResolvedEmbedOptions) => {
|
|
158
|
-
try {
|
|
159
|
-
initialize(options);
|
|
160
|
-
} catch (initErr) {
|
|
161
|
-
console.error("AgentforceConversationClient: initialization failed", initErr);
|
|
162
|
-
singleton.initialized = false;
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const shouldFetchFrontdoor = window.location.hostname === "localhost";
|
|
167
|
-
|
|
168
|
-
if (shouldFetchFrontdoor) {
|
|
169
|
-
singleton.initPromise = fetch("/__lo/frontdoor")
|
|
170
|
-
.then(async (res) => {
|
|
171
|
-
if (!res.ok) {
|
|
172
|
-
console.error("frontdoor fetch failed");
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const { frontdoorUrl: resolvedFrontdoorUrl } = await res.json();
|
|
176
|
-
safeInitialize({ frontdoorUrl: resolvedFrontdoorUrl });
|
|
177
|
-
})
|
|
178
|
-
.catch((err) => {
|
|
179
|
-
console.error("AgentforceConversationClient: failed to fetch frontdoor URL", err);
|
|
180
|
-
})
|
|
181
|
-
.finally(() => {
|
|
182
|
-
singleton.initPromise = undefined;
|
|
183
|
-
});
|
|
184
|
-
} else {
|
|
185
|
-
singleton.initPromise = Promise.resolve()
|
|
186
|
-
.then(() => {
|
|
187
|
-
safeInitialize(getDefaultEmbedOptions());
|
|
188
|
-
})
|
|
189
|
-
.catch((err) => {
|
|
190
|
-
console.error("AgentforceConversationClient: failed to embed Agentforce client", err);
|
|
191
|
-
})
|
|
192
|
-
.finally(() => {
|
|
193
|
-
singleton.initPromise = undefined;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
74
|
+
embedder.embedAcc(
|
|
75
|
+
normalizedAgentforceClientConfig,
|
|
76
|
+
{ salesforceOrigin, frontdoorUrl },
|
|
77
|
+
containerRef.current,
|
|
78
|
+
{ onReady, onError },
|
|
79
|
+
);
|
|
196
80
|
|
|
197
81
|
return () => {
|
|
198
82
|
// Intentionally no cleanup:
|
|
199
83
|
// This component guarantees a single LO initialization per window.
|
|
200
84
|
};
|
|
201
|
-
}, [salesforceOrigin, frontdoorUrl, normalizedAgentforceClientConfig,
|
|
85
|
+
}, [salesforceOrigin, frontdoorUrl, normalizedAgentforceClientConfig, onReady, onError]);
|
|
202
86
|
|
|
203
87
|
if (!inline) {
|
|
204
88
|
return null;
|