@webless/agent 0.7.5 → 0.9.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/README.md +49 -2
- package/dist/chunk-5BCSXCLT.js +297 -0
- package/dist/chunk-5BCSXCLT.js.map +1 -0
- package/dist/{chunk-CD6TKXGT.js → chunk-QMTI5646.js} +69 -40
- package/dist/chunk-QMTI5646.js.map +1 -0
- package/dist/embed.cjs +62 -39
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +98 -0
- package/dist/embed.css.map +1 -1
- package/dist/embed.js +1 -1
- package/dist/index.d.cts +3 -180
- package/dist/index.d.ts +3 -180
- package/dist/index.js +9 -288
- package/dist/index.js.map +1 -1
- package/dist/presentation.cjs +850 -0
- package/dist/presentation.cjs.map +1 -0
- package/dist/presentation.d.cts +160 -0
- package/dist/presentation.d.ts +160 -0
- package/dist/presentation.js +549 -0
- package/dist/presentation.js.map +1 -0
- package/dist/react.cjs +218 -39
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +98 -0
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +26 -3
- package/dist/react.d.ts +26 -3
- package/dist/react.js +163 -2
- package/dist/react.js.map +1 -1
- package/dist/types-ohWeTG9i.d.cts +181 -0
- package/dist/types-ohWeTG9i.d.ts +181 -0
- package/package.json +7 -2
- package/dist/chunk-CD6TKXGT.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,7 +12,6 @@ Sign up at [app.webless.ai](https://app.webless.ai).
|
|
|
12
12
|
|
|
13
13
|
An index is the content your agent answers from. Add your sources (URLs, sitemaps, docs), then publish the index.
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
### 3. Configure your agent in Agent Studio
|
|
17
16
|
|
|
18
17
|
Open **Agent Studio** for your index. Customize the launcher position, appearance, and behavior, then build a preview bundle.
|
|
@@ -27,7 +26,6 @@ After building the bundle, copy the **install snippet** — a single script tag:
|
|
|
27
26
|
|
|
28
27
|
Paste it into your site's HTML, before the closing `</body>` tag. That's the full integration.
|
|
29
28
|
|
|
30
|
-
|
|
31
29
|
## What you get
|
|
32
30
|
|
|
33
31
|
- A collapsible Agent panel on your site.
|
|
@@ -43,3 +41,52 @@ Agent Studio generates a live preview of the agent on your pages, so you can che
|
|
|
43
41
|
## This npm package
|
|
44
42
|
|
|
45
43
|
`@webless/agent` is published for Webless tooling and internal use. It powers the script bundle served from the console install flow.
|
|
44
|
+
|
|
45
|
+
## Render a stored conversation in React
|
|
46
|
+
|
|
47
|
+
`AgentTranscript` reuses the agent's message renderer without connecting to a runtime or creating a session. It renders a snapshot: no composer, feedback, regeneration, or booking actions. Links and source references remain readable; booking controls are disabled.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { AgentTranscript } from "@webless/agent/react";
|
|
51
|
+
import "@webless/agent/react.css";
|
|
52
|
+
|
|
53
|
+
<AgentTranscript
|
|
54
|
+
messages={[
|
|
55
|
+
{
|
|
56
|
+
id: "1",
|
|
57
|
+
role: "visitor",
|
|
58
|
+
text: "Can I book a demo?",
|
|
59
|
+
createdAt: 1789056000000,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "2",
|
|
63
|
+
role: "agent",
|
|
64
|
+
text: "What day works for you?",
|
|
65
|
+
createdAt: 1789056001000,
|
|
66
|
+
},
|
|
67
|
+
]}
|
|
68
|
+
colorScheme="light"
|
|
69
|
+
/>;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The host owns fetching, authorization, pagination, scrolling, and review controls. Pass `ConversationMessage` snapshots with stable IDs and millisecond timestamps. Optional `theme`, `agentLabel`, `visitorLabel`, `label`, and `formatTimestamp` props adapt the presentation to the host. Timestamps default to UTC. Structured references render when supplied in the message; the component does not fetch missing history or tool results.
|
|
73
|
+
|
|
74
|
+
Pass `activities` alongside `messages` to include recorded tool calls and specialist routing. Entries are ordered by their timestamps. Tool result details expand locally; forms and booking controls remain disabled. No runtime connection is created.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
<AgentTranscript
|
|
78
|
+
messages={messages}
|
|
79
|
+
activities={[
|
|
80
|
+
{
|
|
81
|
+
id: "handoff-1",
|
|
82
|
+
callId: "specialist-1",
|
|
83
|
+
createdAt: 1789084800000,
|
|
84
|
+
category: "specialist",
|
|
85
|
+
label: "Product specialist",
|
|
86
|
+
status: "completed",
|
|
87
|
+
},
|
|
88
|
+
]}
|
|
89
|
+
/>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use `presentTranscriptToolResult` from `@webless/agent/presentation` on the server to project stored tool output into the SDK's visitor-facing result cards. This entry point contains no React or CSS imports. Only send the projected presentation to a browser; keep raw tool arguments, provider payloads, and internal prompts server-side. Historical provider errors are represented as failures even when the runtime execution status was completed.
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// src/runtime/tool-ui.ts
|
|
2
|
+
var AGENT_TOOL_UI_SCHEMA_VERSION = "webless.tool-ui.v1";
|
|
3
|
+
var AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION = "webless.structured-tool-input.v1";
|
|
4
|
+
var AGENT_STRUCTURED_TOOL_INPUT_HEADER = "Webless-Structured-Tool-Input-JSON:";
|
|
5
|
+
function formatAgentStructuredToolInput(surface, values) {
|
|
6
|
+
const payload = {
|
|
7
|
+
schemaVersion: AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
|
|
8
|
+
toolSlug: surface.toolSlug,
|
|
9
|
+
...surface.operationId ? { operationId: surface.operationId } : {},
|
|
10
|
+
values
|
|
11
|
+
};
|
|
12
|
+
return `${AGENT_STRUCTURED_TOOL_INPUT_HEADER} ${JSON.stringify(payload)}`;
|
|
13
|
+
}
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
function isJsonValue(value, seen = /* @__PURE__ */ new Set()) {
|
|
18
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
22
|
+
if (typeof value !== "object") return false;
|
|
23
|
+
if (seen.has(value)) return false;
|
|
24
|
+
seen.add(value);
|
|
25
|
+
const valid = Array.isArray(value) ? value.every((item) => isJsonValue(item, seen)) : Object.entries(value).every(
|
|
26
|
+
([key, item]) => typeof key === "string" && isJsonValue(item, seen)
|
|
27
|
+
);
|
|
28
|
+
seen.delete(value);
|
|
29
|
+
return valid;
|
|
30
|
+
}
|
|
31
|
+
function boundedString(value, max) {
|
|
32
|
+
if (typeof value !== "string" || value.trim().length === 0 || value.length > max) {
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
return value.trim();
|
|
36
|
+
}
|
|
37
|
+
function numberValue(value) {
|
|
38
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
39
|
+
}
|
|
40
|
+
function integerValue(value) {
|
|
41
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 8e3 ? value : void 0;
|
|
42
|
+
}
|
|
43
|
+
function isFieldKind(value) {
|
|
44
|
+
return typeof value === "string" && [
|
|
45
|
+
"text",
|
|
46
|
+
"textarea",
|
|
47
|
+
"email",
|
|
48
|
+
"number",
|
|
49
|
+
"select",
|
|
50
|
+
"multi-select",
|
|
51
|
+
"checkbox",
|
|
52
|
+
"confirmation",
|
|
53
|
+
"radio",
|
|
54
|
+
"date",
|
|
55
|
+
"time",
|
|
56
|
+
"date-time",
|
|
57
|
+
"calendar",
|
|
58
|
+
"range",
|
|
59
|
+
"json"
|
|
60
|
+
].includes(value);
|
|
61
|
+
}
|
|
62
|
+
function parseField(value) {
|
|
63
|
+
if (!isRecord(value)) return null;
|
|
64
|
+
if (!hasOnlyKeys(value, [
|
|
65
|
+
"description",
|
|
66
|
+
"kind",
|
|
67
|
+
"label",
|
|
68
|
+
"max",
|
|
69
|
+
"maxItems",
|
|
70
|
+
"maxLength",
|
|
71
|
+
"min",
|
|
72
|
+
"minLength",
|
|
73
|
+
"options",
|
|
74
|
+
"path",
|
|
75
|
+
"placeholder",
|
|
76
|
+
"required",
|
|
77
|
+
"step",
|
|
78
|
+
"defaultValue"
|
|
79
|
+
])) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
if (!isFieldKind(value.kind)) return null;
|
|
83
|
+
const path = boundedString(value.path, 160);
|
|
84
|
+
const label = boundedString(value.label, 160);
|
|
85
|
+
const description = value.description === void 0 ? void 0 : boundedString(value.description, 500);
|
|
86
|
+
const placeholder = value.placeholder === void 0 || typeof value.placeholder !== "string" ? void 0 : value.placeholder;
|
|
87
|
+
const required = value.required === void 0 || typeof value.required !== "boolean" ? void 0 : value.required;
|
|
88
|
+
const min = value.min === void 0 ? void 0 : numberValue(value.min);
|
|
89
|
+
const max = value.max === void 0 ? void 0 : numberValue(value.max);
|
|
90
|
+
const maxItems = value.maxItems === void 0 ? void 0 : integerValue(value.maxItems);
|
|
91
|
+
const step = value.step === void 0 ? void 0 : numberValue(value.step);
|
|
92
|
+
const minLength = value.minLength === void 0 ? void 0 : integerValue(value.minLength);
|
|
93
|
+
const maxLength = value.maxLength === void 0 ? void 0 : integerValue(value.maxLength);
|
|
94
|
+
const defaultValue = value.defaultValue === void 0 || !isJsonValue(value.defaultValue) ? void 0 : value.defaultValue;
|
|
95
|
+
if (!path || !/^[A-Za-z0-9_.[\]-]+$/u.test(path) || !label) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
if (value.description !== void 0 && !description) return null;
|
|
99
|
+
if (value.placeholder !== void 0 && placeholder === void 0) return null;
|
|
100
|
+
if (value.required !== void 0 && required === void 0) return null;
|
|
101
|
+
if (value.min !== void 0 && min === void 0) return null;
|
|
102
|
+
if (value.max !== void 0 && max === void 0) return null;
|
|
103
|
+
if (value.maxItems !== void 0 && (maxItems === void 0 || maxItems < 1 || maxItems > 100))
|
|
104
|
+
return null;
|
|
105
|
+
if (value.step !== void 0 && step === void 0) return null;
|
|
106
|
+
if (value.minLength !== void 0 && minLength === void 0) return null;
|
|
107
|
+
if (value.maxLength !== void 0 && maxLength === void 0) return null;
|
|
108
|
+
if (value.defaultValue !== void 0 && defaultValue === void 0)
|
|
109
|
+
return null;
|
|
110
|
+
if (value.options !== void 0) {
|
|
111
|
+
if (!Array.isArray(value.options) || value.options.length > 100)
|
|
112
|
+
return null;
|
|
113
|
+
for (const option of value.options) {
|
|
114
|
+
if (!isRecord(option) || !boundedString(option.label, 160) || !isJsonValue(option.value)) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
kind: value.kind,
|
|
121
|
+
path,
|
|
122
|
+
label,
|
|
123
|
+
...description ? { description } : {},
|
|
124
|
+
...placeholder !== void 0 ? { placeholder } : {},
|
|
125
|
+
...required !== void 0 ? { required } : {},
|
|
126
|
+
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
127
|
+
...value.options !== void 0 ? { options: value.options } : {},
|
|
128
|
+
...min !== void 0 ? { min } : {},
|
|
129
|
+
...max !== void 0 ? { max } : {},
|
|
130
|
+
...maxItems !== void 0 ? { maxItems } : {},
|
|
131
|
+
...step !== void 0 ? { step } : {},
|
|
132
|
+
...minLength !== void 0 ? { minLength } : {},
|
|
133
|
+
...maxLength !== void 0 ? { maxLength } : {}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function parseStep(value) {
|
|
137
|
+
if (!isRecord(value)) return null;
|
|
138
|
+
if (!hasOnlyKeys(value, ["description", "fieldPaths", "id", "label"])) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const id = boundedString(value.id, 80);
|
|
142
|
+
const label = boundedString(value.label, 160);
|
|
143
|
+
const description = value.description === void 0 ? void 0 : boundedString(value.description, 500);
|
|
144
|
+
if (!id || !/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(id) || !label || value.description !== void 0 && !description || !Array.isArray(value.fieldPaths) || value.fieldPaths.length < 1 || value.fieldPaths.length > 32 || value.fieldPaths.some(
|
|
145
|
+
(path) => typeof path !== "string" || !/^[A-Za-z0-9_.[\]-]+$/u.test(path) || path.length > 160
|
|
146
|
+
)) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
id,
|
|
151
|
+
label,
|
|
152
|
+
fieldPaths: value.fieldPaths,
|
|
153
|
+
...description ? { description } : {}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function parseAction(value) {
|
|
157
|
+
if (!isRecord(value)) return null;
|
|
158
|
+
if (!hasOnlyKeys(value, ["id", "label"])) return null;
|
|
159
|
+
const label = boundedString(value.label, 80);
|
|
160
|
+
if (value.id !== "submit" && value.id !== "back" && value.id !== "next" && value.id !== "reset" || !label) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
id: value.id,
|
|
165
|
+
label
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function parseAgentToolUiSurface(value) {
|
|
169
|
+
if (!isRecord(value) || value.schemaVersion !== AGENT_TOOL_UI_SCHEMA_VERSION)
|
|
170
|
+
return null;
|
|
171
|
+
if (!hasOnlyKeys(value, [
|
|
172
|
+
"actions",
|
|
173
|
+
"description",
|
|
174
|
+
"fields",
|
|
175
|
+
"id",
|
|
176
|
+
"operationId",
|
|
177
|
+
"requestId",
|
|
178
|
+
"schemaVersion",
|
|
179
|
+
"steps",
|
|
180
|
+
"submitLabel",
|
|
181
|
+
"title",
|
|
182
|
+
"toolSlug",
|
|
183
|
+
"values"
|
|
184
|
+
])) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const id = boundedString(value.id, 200);
|
|
188
|
+
const title = boundedString(value.title, 200);
|
|
189
|
+
const toolSlug = boundedString(value.toolSlug, 200);
|
|
190
|
+
const description = value.description === void 0 ? void 0 : boundedString(value.description, 800);
|
|
191
|
+
const operationId = value.operationId === void 0 ? void 0 : boundedString(value.operationId, 200);
|
|
192
|
+
const requestId = value.requestId === void 0 ? void 0 : boundedString(value.requestId, 200);
|
|
193
|
+
const submitLabel = value.submitLabel === void 0 ? void 0 : boundedString(value.submitLabel, 80);
|
|
194
|
+
if (!id || !title || !toolSlug || !Array.isArray(value.fields) || value.fields.length < 1 || value.fields.length > 32) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const fields = value.fields.map(parseField);
|
|
198
|
+
if (fields.some((field) => field === null)) return null;
|
|
199
|
+
const steps = value.steps === void 0 ? void 0 : Array.isArray(value.steps) && value.steps.length <= 8 ? value.steps.map(parseStep) : null;
|
|
200
|
+
if (steps?.some((step) => step === null)) return null;
|
|
201
|
+
const actions = value.actions === void 0 ? void 0 : Array.isArray(value.actions) && value.actions.length <= 8 ? value.actions.map(parseAction) : null;
|
|
202
|
+
if (actions?.some((action) => action === null)) return null;
|
|
203
|
+
if (value.description !== void 0 && !description) return null;
|
|
204
|
+
if (value.operationId !== void 0 && !operationId) return null;
|
|
205
|
+
if (value.requestId !== void 0 && !requestId) return null;
|
|
206
|
+
if (value.submitLabel !== void 0 && !submitLabel) return null;
|
|
207
|
+
const values = value.values !== void 0 && isRecord(value.values) ? value.values : void 0;
|
|
208
|
+
if (value.values !== void 0) {
|
|
209
|
+
if (!values || !Object.values(values).every((item) => isJsonValue(item)))
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
schemaVersion: AGENT_TOOL_UI_SCHEMA_VERSION,
|
|
214
|
+
id,
|
|
215
|
+
title,
|
|
216
|
+
toolSlug,
|
|
217
|
+
fields,
|
|
218
|
+
...actions ? { actions } : {},
|
|
219
|
+
...description ? { description } : {},
|
|
220
|
+
...operationId ? { operationId } : {},
|
|
221
|
+
...requestId ? { requestId } : {},
|
|
222
|
+
...submitLabel ? { submitLabel } : {},
|
|
223
|
+
...steps ? { steps } : {},
|
|
224
|
+
...values ? { values } : {}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function hasOnlyKeys(value, allowed) {
|
|
228
|
+
const allowedKeys = new Set(allowed);
|
|
229
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/runtime/tool-result-envelope.ts
|
|
233
|
+
var ENVELOPE_KEYS = /* @__PURE__ */ new Set([
|
|
234
|
+
"schemaVersion",
|
|
235
|
+
"output",
|
|
236
|
+
"presentationKinds",
|
|
237
|
+
"ui"
|
|
238
|
+
]);
|
|
239
|
+
function isRecord2(value) {
|
|
240
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
241
|
+
}
|
|
242
|
+
function isJsonValue2(value, seen = /* @__PURE__ */ new Set()) {
|
|
243
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
247
|
+
if (typeof value !== "object") return false;
|
|
248
|
+
if (seen.has(value)) return false;
|
|
249
|
+
seen.add(value);
|
|
250
|
+
const valid = Array.isArray(value) ? value.every((item) => isJsonValue2(item, seen)) : Object.entries(value).every(
|
|
251
|
+
([key, item]) => typeof key === "string" && isJsonValue2(item, seen)
|
|
252
|
+
);
|
|
253
|
+
seen.delete(value);
|
|
254
|
+
return valid;
|
|
255
|
+
}
|
|
256
|
+
function decodeEnvelope(value) {
|
|
257
|
+
if (typeof value !== "string") return value;
|
|
258
|
+
try {
|
|
259
|
+
return JSON.parse(value);
|
|
260
|
+
} catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function parseAgentToolResultEnvelope(value) {
|
|
265
|
+
const decoded = decodeEnvelope(value);
|
|
266
|
+
if (!isRecord2(decoded)) return null;
|
|
267
|
+
const keys = Object.keys(decoded);
|
|
268
|
+
if (keys.some((key) => !ENVELOPE_KEYS.has(key)) || decoded.schemaVersion !== "webless.tool-result.v1" || !isJsonValue2(decoded.output) || !Array.isArray(decoded.presentationKinds) || decoded.presentationKinds.length < 1 || decoded.presentationKinds.length > 16) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const presentationKinds = decoded.presentationKinds.flatMap((kind) => {
|
|
272
|
+
if (typeof kind !== "string") return [];
|
|
273
|
+
const normalized = kind.trim();
|
|
274
|
+
return normalized && normalized.length <= 128 ? [normalized] : [];
|
|
275
|
+
});
|
|
276
|
+
if (presentationKinds.length !== decoded.presentationKinds.length) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
const ui = decoded.ui === void 0 ? void 0 : parseAgentToolUiSurface(decoded.ui);
|
|
280
|
+
if (decoded.ui !== void 0 && !ui) return null;
|
|
281
|
+
return {
|
|
282
|
+
schemaVersion: "webless.tool-result.v1",
|
|
283
|
+
output: decoded.output,
|
|
284
|
+
presentationKinds,
|
|
285
|
+
...ui ? { ui } : {}
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export {
|
|
290
|
+
AGENT_TOOL_UI_SCHEMA_VERSION,
|
|
291
|
+
AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
|
|
292
|
+
AGENT_STRUCTURED_TOOL_INPUT_HEADER,
|
|
293
|
+
formatAgentStructuredToolInput,
|
|
294
|
+
parseAgentToolUiSurface,
|
|
295
|
+
parseAgentToolResultEnvelope
|
|
296
|
+
};
|
|
297
|
+
//# sourceMappingURL=chunk-5BCSXCLT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/tool-ui.ts","../src/runtime/tool-result-envelope.ts"],"sourcesContent":["import type { AgentToolResultJsonValue } from \"./tool-result-envelope\";\n\nexport const AGENT_TOOL_UI_SCHEMA_VERSION = \"webless.tool-ui.v1\" as const;\nexport const AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION =\n \"webless.structured-tool-input.v1\" as const;\nexport const AGENT_STRUCTURED_TOOL_INPUT_HEADER =\n \"Webless-Structured-Tool-Input-JSON:\" as const;\n\nexport type AgentToolUiFieldKind =\n | \"text\"\n | \"textarea\"\n | \"email\"\n | \"number\"\n | \"select\"\n | \"multi-select\"\n | \"checkbox\"\n | \"confirmation\"\n | \"radio\"\n | \"date\"\n | \"time\"\n | \"date-time\"\n | \"calendar\"\n | \"range\"\n | \"json\";\n\nexport type AgentToolUiOption = {\n label: string;\n value: AgentToolResultJsonValue;\n};\n\nexport type AgentToolUiField = {\n description?: string;\n kind: AgentToolUiFieldKind;\n label: string;\n max?: number;\n maxItems?: number;\n maxLength?: number;\n min?: number;\n minLength?: number;\n options?: readonly AgentToolUiOption[];\n path: string;\n placeholder?: string;\n required?: boolean;\n step?: number;\n defaultValue?: AgentToolResultJsonValue;\n};\n\nexport type AgentToolUiStep = {\n description?: string;\n fieldPaths: readonly string[];\n id: string;\n label: string;\n};\n\nexport type AgentToolUiAction = {\n id: \"submit\" | \"back\" | \"next\" | \"reset\";\n label: string;\n};\n\nexport type AgentToolUiSurface = {\n actions?: readonly AgentToolUiAction[];\n description?: string;\n fields: readonly AgentToolUiField[];\n id: string;\n operationId?: string;\n requestId?: string;\n schemaVersion: typeof AGENT_TOOL_UI_SCHEMA_VERSION;\n steps?: readonly AgentToolUiStep[];\n submitLabel?: string;\n title: string;\n toolSlug: string;\n values?: Readonly<Record<string, AgentToolResultJsonValue>>;\n};\n\nexport type AgentStructuredToolInput = {\n schemaVersion: typeof AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION;\n operationId?: string;\n toolSlug: string;\n values: Readonly<Record<string, AgentToolResultJsonValue>>;\n};\n\nexport function formatAgentStructuredToolInput(\n surface: AgentToolUiSurface,\n values: Readonly<Record<string, AgentToolResultJsonValue>>\n) {\n const payload: AgentStructuredToolInput = {\n schemaVersion: AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,\n toolSlug: surface.toolSlug,\n ...(surface.operationId ? { operationId: surface.operationId } : {}),\n values,\n };\n return `${AGENT_STRUCTURED_TOOL_INPUT_HEADER} ${JSON.stringify(payload)}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isJsonValue(\n value: unknown,\n seen = new Set<object>()\n): value is AgentToolResultJsonValue {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n if (typeof value === \"number\") return Number.isFinite(value);\n if (typeof value !== \"object\") return false;\n if (seen.has(value)) return false;\n seen.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonValue(item, seen))\n : Object.entries(value).every(\n ([key, item]) => typeof key === \"string\" && isJsonValue(item, seen)\n );\n seen.delete(value);\n return valid;\n}\n\nfunction boundedString(value: unknown, max: number) {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0 ||\n value.length > max\n ) {\n return undefined;\n }\n return value.trim();\n}\n\nfunction numberValue(value: unknown) {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction integerValue(value: unknown) {\n return typeof value === \"number\" &&\n Number.isInteger(value) &&\n value >= 0 &&\n value <= 8_000\n ? value\n : undefined;\n}\n\nfunction isFieldKind(value: unknown): value is AgentToolUiFieldKind {\n return (\n typeof value === \"string\" &&\n [\n \"text\",\n \"textarea\",\n \"email\",\n \"number\",\n \"select\",\n \"multi-select\",\n \"checkbox\",\n \"confirmation\",\n \"radio\",\n \"date\",\n \"time\",\n \"date-time\",\n \"calendar\",\n \"range\",\n \"json\",\n ].includes(value)\n );\n}\n\nfunction parseField(value: unknown): AgentToolUiField | null {\n if (!isRecord(value)) return null;\n if (\n !hasOnlyKeys(value, [\n \"description\",\n \"kind\",\n \"label\",\n \"max\",\n \"maxItems\",\n \"maxLength\",\n \"min\",\n \"minLength\",\n \"options\",\n \"path\",\n \"placeholder\",\n \"required\",\n \"step\",\n \"defaultValue\",\n ])\n ) {\n return null;\n }\n if (!isFieldKind(value.kind)) return null;\n const path = boundedString(value.path, 160);\n const label = boundedString(value.label, 160);\n const description =\n value.description === undefined\n ? undefined\n : boundedString(value.description, 500);\n const placeholder =\n value.placeholder === undefined || typeof value.placeholder !== \"string\"\n ? undefined\n : value.placeholder;\n const required =\n value.required === undefined || typeof value.required !== \"boolean\"\n ? undefined\n : value.required;\n const min = value.min === undefined ? undefined : numberValue(value.min);\n const max = value.max === undefined ? undefined : numberValue(value.max);\n const maxItems =\n value.maxItems === undefined ? undefined : integerValue(value.maxItems);\n const step = value.step === undefined ? undefined : numberValue(value.step);\n const minLength =\n value.minLength === undefined ? undefined : integerValue(value.minLength);\n const maxLength =\n value.maxLength === undefined ? undefined : integerValue(value.maxLength);\n const defaultValue =\n value.defaultValue === undefined || !isJsonValue(value.defaultValue)\n ? undefined\n : value.defaultValue;\n if (!path || !/^[A-Za-z0-9_.[\\]-]+$/u.test(path) || !label) {\n return null;\n }\n if (value.description !== undefined && !description) return null;\n if (value.placeholder !== undefined && placeholder === undefined) return null;\n if (value.required !== undefined && required === undefined) return null;\n if (value.min !== undefined && min === undefined) return null;\n if (value.max !== undefined && max === undefined) return null;\n if (\n value.maxItems !== undefined &&\n (maxItems === undefined || maxItems < 1 || maxItems > 100)\n )\n return null;\n if (value.step !== undefined && step === undefined) return null;\n if (value.minLength !== undefined && minLength === undefined) return null;\n if (value.maxLength !== undefined && maxLength === undefined) return null;\n if (value.defaultValue !== undefined && defaultValue === undefined)\n return null;\n if (value.options !== undefined) {\n if (!Array.isArray(value.options) || value.options.length > 100)\n return null;\n for (const option of value.options) {\n if (\n !isRecord(option) ||\n !boundedString(option.label, 160) ||\n !isJsonValue(option.value)\n ) {\n return null;\n }\n }\n }\n return {\n kind: value.kind,\n path,\n label,\n ...(description ? { description } : {}),\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(required !== undefined ? { required } : {}),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\n ...(value.options !== undefined\n ? { options: value.options as AgentToolUiOption[] }\n : {}),\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n ...(maxItems !== undefined ? { maxItems } : {}),\n ...(step !== undefined ? { step } : {}),\n ...(minLength !== undefined ? { minLength } : {}),\n ...(maxLength !== undefined ? { maxLength } : {}),\n };\n}\n\nfunction parseStep(value: unknown): AgentToolUiStep | null {\n if (!isRecord(value)) return null;\n if (!hasOnlyKeys(value, [\"description\", \"fieldPaths\", \"id\", \"label\"])) {\n return null;\n }\n const id = boundedString(value.id, 80);\n const label = boundedString(value.label, 160);\n const description =\n value.description === undefined\n ? undefined\n : boundedString(value.description, 500);\n if (\n !id ||\n !/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(id) ||\n !label ||\n (value.description !== undefined && !description) ||\n !Array.isArray(value.fieldPaths) ||\n value.fieldPaths.length < 1 ||\n value.fieldPaths.length > 32 ||\n value.fieldPaths.some(\n (path) =>\n typeof path !== \"string\" ||\n !/^[A-Za-z0-9_.[\\]-]+$/u.test(path) ||\n path.length > 160\n )\n ) {\n return null;\n }\n return {\n id,\n label,\n fieldPaths: value.fieldPaths,\n ...(description ? { description } : {}),\n };\n}\n\nfunction parseAction(value: unknown): AgentToolUiAction | null {\n if (!isRecord(value)) return null;\n if (!hasOnlyKeys(value, [\"id\", \"label\"])) return null;\n const label = boundedString(value.label, 80);\n if (\n (value.id !== \"submit\" &&\n value.id !== \"back\" &&\n value.id !== \"next\" &&\n value.id !== \"reset\") ||\n !label\n ) {\n return null;\n }\n return {\n id: value.id,\n label,\n };\n}\n\nexport function parseAgentToolUiSurface(\n value: unknown\n): AgentToolUiSurface | null {\n if (!isRecord(value) || value.schemaVersion !== AGENT_TOOL_UI_SCHEMA_VERSION)\n return null;\n if (\n !hasOnlyKeys(value, [\n \"actions\",\n \"description\",\n \"fields\",\n \"id\",\n \"operationId\",\n \"requestId\",\n \"schemaVersion\",\n \"steps\",\n \"submitLabel\",\n \"title\",\n \"toolSlug\",\n \"values\",\n ])\n ) {\n return null;\n }\n const id = boundedString(value.id, 200);\n const title = boundedString(value.title, 200);\n const toolSlug = boundedString(value.toolSlug, 200);\n const description =\n value.description === undefined\n ? undefined\n : boundedString(value.description, 800);\n const operationId =\n value.operationId === undefined\n ? undefined\n : boundedString(value.operationId, 200);\n const requestId =\n value.requestId === undefined\n ? undefined\n : boundedString(value.requestId, 200);\n const submitLabel =\n value.submitLabel === undefined\n ? undefined\n : boundedString(value.submitLabel, 80);\n if (\n !id ||\n !title ||\n !toolSlug ||\n !Array.isArray(value.fields) ||\n value.fields.length < 1 ||\n value.fields.length > 32\n ) {\n return null;\n }\n const fields = value.fields.map(parseField);\n if (fields.some((field) => field === null)) return null;\n const steps =\n value.steps === undefined\n ? undefined\n : Array.isArray(value.steps) && value.steps.length <= 8\n ? value.steps.map(parseStep)\n : null;\n if (steps?.some((step) => step === null)) return null;\n const actions =\n value.actions === undefined\n ? undefined\n : Array.isArray(value.actions) && value.actions.length <= 8\n ? value.actions.map(parseAction)\n : null;\n if (actions?.some((action) => action === null)) return null;\n if (value.description !== undefined && !description) return null;\n if (value.operationId !== undefined && !operationId) return null;\n if (value.requestId !== undefined && !requestId) return null;\n if (value.submitLabel !== undefined && !submitLabel) return null;\n const values =\n value.values !== undefined && isRecord(value.values)\n ? value.values\n : undefined;\n if (value.values !== undefined) {\n if (!values || !Object.values(values).every((item) => isJsonValue(item)))\n return null;\n }\n return {\n schemaVersion: AGENT_TOOL_UI_SCHEMA_VERSION,\n id,\n title,\n toolSlug,\n fields: fields as AgentToolUiField[],\n ...(actions ? { actions: actions as AgentToolUiAction[] } : {}),\n ...(description ? { description } : {}),\n ...(operationId ? { operationId } : {}),\n ...(requestId ? { requestId } : {}),\n ...(submitLabel ? { submitLabel } : {}),\n ...(steps ? { steps: steps as AgentToolUiStep[] } : {}),\n ...(values\n ? { values: values as Record<string, AgentToolResultJsonValue> }\n : {}),\n };\n}\n\nfunction hasOnlyKeys(\n value: Record<string, unknown>,\n allowed: readonly string[]\n) {\n const allowedKeys = new Set(allowed);\n return Object.keys(value).every((key) => allowedKeys.has(key));\n}\n","import { parseAgentToolUiSurface, type AgentToolUiSurface } from \"./tool-ui\";\n\nexport type AgentToolResultJsonValue =\n | null\n | boolean\n | number\n | string\n | AgentToolResultJsonValue[]\n | { [key: string]: AgentToolResultJsonValue };\n\nexport type AgentToolResultEnvelope = {\n schemaVersion: \"webless.tool-result.v1\";\n output: AgentToolResultJsonValue;\n presentationKinds: string[];\n ui?: AgentToolUiSurface;\n};\n\nconst ENVELOPE_KEYS = new Set([\n \"schemaVersion\",\n \"output\",\n \"presentationKinds\",\n \"ui\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isJsonValue(\n value: unknown,\n seen: Set<object> = new Set()\n): value is AgentToolResultJsonValue {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n if (typeof value === \"number\") return Number.isFinite(value);\n if (typeof value !== \"object\") return false;\n if (seen.has(value)) return false;\n seen.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonValue(item, seen))\n : Object.entries(value).every(\n ([key, item]) => typeof key === \"string\" && isJsonValue(item, seen)\n );\n seen.delete(value);\n return valid;\n}\n\nfunction decodeEnvelope(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return null;\n }\n}\n\nexport function parseAgentToolResultEnvelope(\n value: unknown\n): AgentToolResultEnvelope | null {\n const decoded = decodeEnvelope(value);\n if (!isRecord(decoded)) return null;\n const keys = Object.keys(decoded);\n if (\n keys.some((key) => !ENVELOPE_KEYS.has(key)) ||\n decoded.schemaVersion !== \"webless.tool-result.v1\" ||\n !isJsonValue(decoded.output) ||\n !Array.isArray(decoded.presentationKinds) ||\n decoded.presentationKinds.length < 1 ||\n decoded.presentationKinds.length > 16\n ) {\n return null;\n }\n const presentationKinds = decoded.presentationKinds.flatMap((kind) => {\n if (typeof kind !== \"string\") return [];\n const normalized = kind.trim();\n return normalized && normalized.length <= 128 ? [normalized] : [];\n });\n if (presentationKinds.length !== decoded.presentationKinds.length) {\n return null;\n }\n const ui =\n decoded.ui === undefined ? undefined : parseAgentToolUiSurface(decoded.ui);\n if (decoded.ui !== undefined && !ui) return null;\n return {\n schemaVersion: \"webless.tool-result.v1\",\n output: decoded.output,\n presentationKinds,\n ...(ui ? { ui } : {}),\n };\n}\n"],"mappings":"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","names":["isRecord","isJsonValue"]}
|
|
@@ -4074,6 +4074,48 @@ function MessageActions({
|
|
|
4074
4074
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
4075
4075
|
import { useEffect as useEffect6, useRef as useRef6, useState as useState9 } from "react";
|
|
4076
4076
|
|
|
4077
|
+
// src/react/lib/agent-theme.ts
|
|
4078
|
+
function agentThemeStyle(theme, resolvedColorScheme) {
|
|
4079
|
+
const brandedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
4080
|
+
const resolvedTheme = resolvedColorScheme === "dark" ? {
|
|
4081
|
+
...brandedTheme,
|
|
4082
|
+
brand: theme?.brand ?? defaultDarkAgentRailTheme.brand,
|
|
4083
|
+
brandDeep: theme?.brandDeep ?? defaultDarkAgentRailTheme.brandDeep,
|
|
4084
|
+
brandSoft: theme?.brandSoft ?? `color-mix(in srgb, ${theme?.brand ?? defaultDarkAgentRailTheme.brand} 18%, ${defaultDarkAgentRailTheme.surface})`,
|
|
4085
|
+
border: theme?.border ?? defaultDarkAgentRailTheme.border,
|
|
4086
|
+
danger: theme?.danger ?? defaultDarkAgentRailTheme.danger,
|
|
4087
|
+
onBrand: theme?.onBrand ?? defaultDarkAgentRailTheme.onBrand,
|
|
4088
|
+
success: theme?.success ?? defaultDarkAgentRailTheme.success,
|
|
4089
|
+
surface: theme?.surface ?? defaultDarkAgentRailTheme.surface,
|
|
4090
|
+
surfaceMuted: theme?.surfaceMuted ?? defaultDarkAgentRailTheme.surfaceMuted,
|
|
4091
|
+
text: theme?.text ?? defaultDarkAgentRailTheme.text,
|
|
4092
|
+
textMuted: theme?.textMuted ?? defaultDarkAgentRailTheme.textMuted,
|
|
4093
|
+
textSubtle: theme?.textSubtle ?? defaultDarkAgentRailTheme.textSubtle,
|
|
4094
|
+
visitorBubble: theme?.visitorBubble ?? theme?.brand ?? defaultDarkAgentRailTheme.visitorBubble
|
|
4095
|
+
} : brandedTheme;
|
|
4096
|
+
return {
|
|
4097
|
+
"--rail-width": resolvedTheme.railMaxWidth,
|
|
4098
|
+
"--as-rail-max-width": resolvedTheme.railMaxWidth,
|
|
4099
|
+
"--as-brand": resolvedTheme.brand,
|
|
4100
|
+
"--as-brand-soft": resolvedTheme.brandSoft,
|
|
4101
|
+
"--as-brand-deep": resolvedTheme.brandDeep,
|
|
4102
|
+
"--as-surface": resolvedTheme.surface,
|
|
4103
|
+
"--as-surface-muted": resolvedTheme.surfaceMuted,
|
|
4104
|
+
"--as-text": resolvedTheme.text,
|
|
4105
|
+
"--as-text-muted": resolvedTheme.textMuted,
|
|
4106
|
+
"--as-text-subtle": resolvedTheme.textSubtle,
|
|
4107
|
+
"--as-border": resolvedTheme.border,
|
|
4108
|
+
"--as-visitor-bubble": resolvedTheme.visitorBubble,
|
|
4109
|
+
"--as-visitor-text": resolvedTheme.visitorText,
|
|
4110
|
+
"--as-on-brand": resolvedTheme.onBrand,
|
|
4111
|
+
"--as-success": resolvedTheme.success,
|
|
4112
|
+
"--as-danger": resolvedTheme.danger,
|
|
4113
|
+
"--as-font-body": resolvedTheme.fontBody,
|
|
4114
|
+
"--as-font-display": resolvedTheme.fontDisplay,
|
|
4115
|
+
colorScheme: resolvedColorScheme
|
|
4116
|
+
};
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4077
4119
|
// src/react/hooks/useAgentColorScheme.ts
|
|
4078
4120
|
import { useSyncExternalStore } from "react";
|
|
4079
4121
|
var DARK_MODE_QUERY = "(prefers-color-scheme: dark)";
|
|
@@ -4820,7 +4862,23 @@ function calendarCells(year, month) {
|
|
|
4820
4862
|
function BookingCardLoader() {
|
|
4821
4863
|
return /* @__PURE__ */ jsx7("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsx7("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
|
|
4822
4864
|
}
|
|
4823
|
-
function BookingCard({
|
|
4865
|
+
function BookingCard(props) {
|
|
4866
|
+
if (!props.readOnly) return /* @__PURE__ */ jsx7(InteractiveBookingCard, { ...props });
|
|
4867
|
+
return /* @__PURE__ */ jsxs7("section", { className: "booking-card", "aria-label": "Recorded available times", children: [
|
|
4868
|
+
/* @__PURE__ */ jsx7("p", { className: "booking-card__title", children: "Available times offered" }),
|
|
4869
|
+
props.offer.slots.length ? /* @__PURE__ */ jsx7("ul", { children: props.offer.slots.map((slot, index) => {
|
|
4870
|
+
const eventType = props.offer.eventTypes.find(
|
|
4871
|
+
(item) => item.uri === slot.eventTypeUri
|
|
4872
|
+
);
|
|
4873
|
+
const label = Number.isFinite(Date.parse(slot.startTime)) ? formatSlotLabel(slot.startTime) : "Time unavailable";
|
|
4874
|
+
return /* @__PURE__ */ jsxs7("li", { children: [
|
|
4875
|
+
eventType ? `${eventType.name} \xB7 ` : "",
|
|
4876
|
+
label
|
|
4877
|
+
] }, `${slot.eventTypeUri ?? ""}:${slot.startTime}:${index}`);
|
|
4878
|
+
}) }) : /* @__PURE__ */ jsx7("p", { children: "No available times were recorded." })
|
|
4879
|
+
] });
|
|
4880
|
+
}
|
|
4881
|
+
function InteractiveBookingCard({
|
|
4824
4882
|
disabled = false,
|
|
4825
4883
|
offer,
|
|
4826
4884
|
onBook
|
|
@@ -5186,6 +5244,7 @@ function MessageBubble({
|
|
|
5186
5244
|
message,
|
|
5187
5245
|
brandLogoUrl,
|
|
5188
5246
|
bookingDisabled = false,
|
|
5247
|
+
bookingReadOnly = false,
|
|
5189
5248
|
offer,
|
|
5190
5249
|
onBook
|
|
5191
5250
|
}) {
|
|
@@ -5252,6 +5311,7 @@ function MessageBubble({
|
|
|
5252
5311
|
BookingCard,
|
|
5253
5312
|
{
|
|
5254
5313
|
disabled: bookingDisabled,
|
|
5314
|
+
readOnly: bookingReadOnly,
|
|
5255
5315
|
offer: nextOffer,
|
|
5256
5316
|
onBook
|
|
5257
5317
|
},
|
|
@@ -6070,44 +6130,7 @@ function AgentRail({
|
|
|
6070
6130
|
const [failedLogoUrl, setFailedLogoUrl] = useState9(null);
|
|
6071
6131
|
const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
|
|
6072
6132
|
const resolvedColorScheme = useAgentColorScheme(colorScheme);
|
|
6073
|
-
const
|
|
6074
|
-
const resolvedTheme = resolvedColorScheme === "dark" ? {
|
|
6075
|
-
...brandedTheme,
|
|
6076
|
-
brand: theme?.brand ?? defaultDarkAgentRailTheme.brand,
|
|
6077
|
-
brandDeep: theme?.brandDeep ?? defaultDarkAgentRailTheme.brandDeep,
|
|
6078
|
-
brandSoft: theme?.brandSoft ?? `color-mix(in srgb, ${theme?.brand ?? defaultDarkAgentRailTheme.brand} 18%, ${defaultDarkAgentRailTheme.surface})`,
|
|
6079
|
-
border: theme?.border ?? defaultDarkAgentRailTheme.border,
|
|
6080
|
-
danger: theme?.danger ?? defaultDarkAgentRailTheme.danger,
|
|
6081
|
-
onBrand: theme?.onBrand ?? defaultDarkAgentRailTheme.onBrand,
|
|
6082
|
-
success: theme?.success ?? defaultDarkAgentRailTheme.success,
|
|
6083
|
-
surface: theme?.surface ?? defaultDarkAgentRailTheme.surface,
|
|
6084
|
-
surfaceMuted: theme?.surfaceMuted ?? defaultDarkAgentRailTheme.surfaceMuted,
|
|
6085
|
-
text: theme?.text ?? defaultDarkAgentRailTheme.text,
|
|
6086
|
-
textMuted: theme?.textMuted ?? defaultDarkAgentRailTheme.textMuted,
|
|
6087
|
-
textSubtle: theme?.textSubtle ?? defaultDarkAgentRailTheme.textSubtle,
|
|
6088
|
-
visitorBubble: theme?.visitorBubble ?? theme?.brand ?? defaultDarkAgentRailTheme.visitorBubble
|
|
6089
|
-
} : brandedTheme;
|
|
6090
|
-
const railStyle = {
|
|
6091
|
-
"--rail-width": resolvedTheme.railMaxWidth,
|
|
6092
|
-
"--as-rail-max-width": resolvedTheme.railMaxWidth,
|
|
6093
|
-
"--as-brand": resolvedTheme.brand,
|
|
6094
|
-
"--as-brand-soft": resolvedTheme.brandSoft,
|
|
6095
|
-
"--as-brand-deep": resolvedTheme.brandDeep,
|
|
6096
|
-
"--as-surface": resolvedTheme.surface,
|
|
6097
|
-
"--as-surface-muted": resolvedTheme.surfaceMuted,
|
|
6098
|
-
"--as-text": resolvedTheme.text,
|
|
6099
|
-
"--as-text-muted": resolvedTheme.textMuted,
|
|
6100
|
-
"--as-text-subtle": resolvedTheme.textSubtle,
|
|
6101
|
-
"--as-border": resolvedTheme.border,
|
|
6102
|
-
"--as-visitor-bubble": resolvedTheme.visitorBubble,
|
|
6103
|
-
"--as-visitor-text": resolvedTheme.visitorText,
|
|
6104
|
-
"--as-on-brand": resolvedTheme.onBrand,
|
|
6105
|
-
"--as-success": resolvedTheme.success,
|
|
6106
|
-
"--as-danger": resolvedTheme.danger,
|
|
6107
|
-
"--as-font-body": resolvedTheme.fontBody,
|
|
6108
|
-
"--as-font-display": resolvedTheme.fontDisplay,
|
|
6109
|
-
colorScheme: resolvedColorScheme
|
|
6110
|
-
};
|
|
6133
|
+
const railStyle = agentThemeStyle(theme, resolvedColorScheme);
|
|
6111
6134
|
const pendingInputRequests = (state.pendingInputs ?? []).filter(
|
|
6112
6135
|
(request) => shouldRenderVisitorInputCard(request) && (!state.pendingOffer || request.kind === "tool-approval")
|
|
6113
6136
|
);
|
|
@@ -7123,7 +7146,13 @@ export {
|
|
|
7123
7146
|
submitAgentPanel,
|
|
7124
7147
|
defaultAgentRailTheme,
|
|
7125
7148
|
defaultDarkAgentRailTheme,
|
|
7149
|
+
agentThemeStyle,
|
|
7150
|
+
useAgentColorScheme,
|
|
7151
|
+
SearchReferences,
|
|
7152
|
+
BookingCard,
|
|
7153
|
+
MessageBubble,
|
|
7126
7154
|
MessageActions,
|
|
7155
|
+
VisitorToolResultView,
|
|
7127
7156
|
AgentRail,
|
|
7128
7157
|
AssistEdgeTab,
|
|
7129
7158
|
AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
|
|
@@ -7132,4 +7161,4 @@ export {
|
|
|
7132
7161
|
sendAgentAnswerFeedback,
|
|
7133
7162
|
AgentWidget
|
|
7134
7163
|
};
|
|
7135
|
-
//# sourceMappingURL=chunk-
|
|
7164
|
+
//# sourceMappingURL=chunk-QMTI5646.js.map
|