@hef2024/llmasaservice-ui 0.25.2 → 0.26.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/index.css +439 -2
- package/dist/index.d.mts +68 -1
- package/dist/index.d.ts +68 -1
- package/dist/index.js +832 -159
- package/dist/index.mjs +832 -159
- package/hef2024-llmasaservice-ui-0.25.3.tgz +0 -0
- package/index.ts +5 -0
- package/package.json +12 -1
- package/src/AIAgentPanel.css +16 -2
- package/src/AIAgentPanel.tsx +122 -4
- package/src/AIChatPanel.css +497 -1
- package/src/AIChatPanel.tsx +1085 -223
package/dist/index.mjs
CHANGED
|
@@ -4153,6 +4153,58 @@ var ToolInfoModal2 = ({
|
|
|
4153
4153
|
var ToolInfoModal_default2 = ToolInfoModal2;
|
|
4154
4154
|
|
|
4155
4155
|
// src/AIChatPanel.tsx
|
|
4156
|
+
var USER_INPUT_TOOL_NAMES = /* @__PURE__ */ new Set(["request_user_input", "ff_request_user_input"]);
|
|
4157
|
+
var MAX_USER_INPUT_QUESTIONS = 5;
|
|
4158
|
+
var MAX_USER_INPUT_OPTIONS = 8;
|
|
4159
|
+
var MAX_USER_INPUT_WRITE_IN_CHARS = 1e3;
|
|
4160
|
+
var DEFAULT_USER_INPUT_TITLE = "Need your input";
|
|
4161
|
+
var DEFAULT_USER_INPUT_INSTRUCTIONS = "Answer these quick questions to continue.";
|
|
4162
|
+
var DEFAULT_CONTEXT_WARN_RATIO = 0.7;
|
|
4163
|
+
var DEFAULT_CONTEXT_COMPACT_RATIO = 0.9;
|
|
4164
|
+
var DEFAULT_CONTEXT_TARGET_RATIO = 0.65;
|
|
4165
|
+
var DEFAULT_COMPACTION_PRESERVE_TURNS = 8;
|
|
4166
|
+
function toBoundedRatio(value, fallback) {
|
|
4167
|
+
if (!Number.isFinite(value)) return fallback;
|
|
4168
|
+
if (value <= 0) return fallback;
|
|
4169
|
+
if (value >= 1) return 1;
|
|
4170
|
+
return value;
|
|
4171
|
+
}
|
|
4172
|
+
function estimateTokensFromText(text) {
|
|
4173
|
+
const normalized = typeof text === "string" ? text : "";
|
|
4174
|
+
if (!normalized) return 0;
|
|
4175
|
+
return Math.ceil(normalized.length / 4);
|
|
4176
|
+
}
|
|
4177
|
+
function estimateTokensFromMessages(messages) {
|
|
4178
|
+
if (!Array.isArray(messages) || messages.length === 0) return 0;
|
|
4179
|
+
return messages.reduce((sum, message) => {
|
|
4180
|
+
const role = typeof (message == null ? void 0 : message.role) === "string" ? message.role : "";
|
|
4181
|
+
const content = typeof (message == null ? void 0 : message.content) === "string" ? message.content : "";
|
|
4182
|
+
return sum + estimateTokensFromText(role) + estimateTokensFromText(content);
|
|
4183
|
+
}, 0);
|
|
4184
|
+
}
|
|
4185
|
+
function estimateTokensFromData(data) {
|
|
4186
|
+
if (!Array.isArray(data) || data.length === 0) return 0;
|
|
4187
|
+
return data.reduce((sum, entry) => {
|
|
4188
|
+
const key = typeof (entry == null ? void 0 : entry.key) === "string" ? entry.key : "";
|
|
4189
|
+
const value = typeof (entry == null ? void 0 : entry.data) === "string" ? entry.data : "";
|
|
4190
|
+
return sum + estimateTokensFromText(key) + estimateTokensFromText(value);
|
|
4191
|
+
}, 0);
|
|
4192
|
+
}
|
|
4193
|
+
function formatTokenCount(tokens) {
|
|
4194
|
+
const safeTokens = Number.isFinite(tokens) ? Math.max(0, Math.floor(tokens)) : 0;
|
|
4195
|
+
if (safeTokens >= 1e3) {
|
|
4196
|
+
return `${(safeTokens / 1e3).toFixed(1)}K`;
|
|
4197
|
+
}
|
|
4198
|
+
return safeTokens.toString();
|
|
4199
|
+
}
|
|
4200
|
+
function buildFallbackWindowMessages(messages, preserveTurns) {
|
|
4201
|
+
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
4202
|
+
const keepMessageCount = Math.max(2, Math.floor(preserveTurns) * 2);
|
|
4203
|
+
if (messages.length <= keepMessageCount) {
|
|
4204
|
+
return messages;
|
|
4205
|
+
}
|
|
4206
|
+
return messages.slice(messages.length - keepMessageCount);
|
|
4207
|
+
}
|
|
4156
4208
|
var areToolRequestListsEqual = (a, b) => {
|
|
4157
4209
|
if (a.length !== b.length) return false;
|
|
4158
4210
|
for (let index = 0; index < a.length; index += 1) {
|
|
@@ -4226,6 +4278,106 @@ var shouldPreserveBoundaryDroppedStreamText = (existingContent, incomingContent)
|
|
|
4226
4278
|
return isBoundarySubsetByLines(existingLines, incomingLines);
|
|
4227
4279
|
};
|
|
4228
4280
|
var isObjectRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
4281
|
+
var toTrimmedString = (value) => typeof value === "string" ? value.trim() : "";
|
|
4282
|
+
var toBooleanWithDefault = (value, fallback) => typeof value === "boolean" ? value : fallback;
|
|
4283
|
+
var parseMaybeJsonString = (value) => {
|
|
4284
|
+
if (typeof value !== "string") return value;
|
|
4285
|
+
const trimmed = value.trim();
|
|
4286
|
+
if (!trimmed) return value;
|
|
4287
|
+
if (!(trimmed.startsWith("{") || trimmed.startsWith("["))) return value;
|
|
4288
|
+
try {
|
|
4289
|
+
return JSON.parse(trimmed);
|
|
4290
|
+
} catch (_error) {
|
|
4291
|
+
return value;
|
|
4292
|
+
}
|
|
4293
|
+
};
|
|
4294
|
+
var toArrayFromUnknown = (value) => {
|
|
4295
|
+
const parsed = parseMaybeJsonString(value);
|
|
4296
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
4297
|
+
};
|
|
4298
|
+
var toSlugValue = (value, fallback) => {
|
|
4299
|
+
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4300
|
+
return normalized || fallback;
|
|
4301
|
+
};
|
|
4302
|
+
var normalizeUserInputOptionEntry = (value, optionIndex, questionId) => {
|
|
4303
|
+
const normalizedValue = parseMaybeJsonString(value);
|
|
4304
|
+
if (typeof normalizedValue === "string") {
|
|
4305
|
+
const label2 = normalizedValue.trim();
|
|
4306
|
+
if (!label2) return null;
|
|
4307
|
+
return {
|
|
4308
|
+
label: label2,
|
|
4309
|
+
value: toSlugValue(label2, `${questionId}-option-${optionIndex + 1}`),
|
|
4310
|
+
description: ""
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
if (!isObjectRecord(normalizedValue)) return null;
|
|
4314
|
+
const label = toTrimmedString(normalizedValue.label) || toTrimmedString(normalizedValue.title) || toTrimmedString(normalizedValue.value);
|
|
4315
|
+
if (!label) return null;
|
|
4316
|
+
const explicitValue = toTrimmedString(normalizedValue.value);
|
|
4317
|
+
return {
|
|
4318
|
+
label,
|
|
4319
|
+
value: explicitValue || toSlugValue(label, `${questionId}-option-${optionIndex + 1}`),
|
|
4320
|
+
description: toTrimmedString(normalizedValue.description)
|
|
4321
|
+
};
|
|
4322
|
+
};
|
|
4323
|
+
var normalizeUserInputQuestionEntry = (value, questionIndex) => {
|
|
4324
|
+
const normalizedValue = parseMaybeJsonString(value);
|
|
4325
|
+
if (!isObjectRecord(normalizedValue)) return null;
|
|
4326
|
+
const fallbackId = `question_${questionIndex + 1}`;
|
|
4327
|
+
const id = toSlugValue(
|
|
4328
|
+
toTrimmedString(normalizedValue.id) || toTrimmedString(normalizedValue.key) || fallbackId,
|
|
4329
|
+
fallbackId
|
|
4330
|
+
);
|
|
4331
|
+
const header = toTrimmedString(normalizedValue.header) || `Question ${questionIndex + 1}`;
|
|
4332
|
+
const question = toTrimmedString(normalizedValue.question) || toTrimmedString(normalizedValue.prompt) || toTrimmedString(normalizedValue.text);
|
|
4333
|
+
if (!question) return null;
|
|
4334
|
+
const rawOptions = toArrayFromUnknown(normalizedValue.options);
|
|
4335
|
+
const normalizedOptions = rawOptions.map((entry, optionIndex) => normalizeUserInputOptionEntry(entry, optionIndex, id)).filter((entry) => Boolean(entry)).slice(0, MAX_USER_INPUT_OPTIONS);
|
|
4336
|
+
if (normalizedOptions.length === 0) {
|
|
4337
|
+
return null;
|
|
4338
|
+
}
|
|
4339
|
+
const parsedWriteInConfig = parseMaybeJsonString(normalizedValue.writeIn);
|
|
4340
|
+
const writeInConfig = isObjectRecord(parsedWriteInConfig) ? parsedWriteInConfig : null;
|
|
4341
|
+
const allowWriteIn = toBooleanWithDefault(normalizedValue.allowWriteIn, false) || toBooleanWithDefault(writeInConfig == null ? void 0 : writeInConfig.enabled, false);
|
|
4342
|
+
const writeInPlaceholder = toTrimmedString(normalizedValue.writeInPlaceholder) || toTrimmedString(writeInConfig == null ? void 0 : writeInConfig.placeholder) || "Add details";
|
|
4343
|
+
return {
|
|
4344
|
+
id,
|
|
4345
|
+
header,
|
|
4346
|
+
question,
|
|
4347
|
+
required: toBooleanWithDefault(normalizedValue.required, true),
|
|
4348
|
+
allowWriteIn,
|
|
4349
|
+
writeInPlaceholder,
|
|
4350
|
+
options: normalizedOptions
|
|
4351
|
+
};
|
|
4352
|
+
};
|
|
4353
|
+
var normalizeUserInputRequest = (args, callId) => {
|
|
4354
|
+
const rawQuestions = toArrayFromUnknown(args.questions);
|
|
4355
|
+
const fallbackQuestion = toTrimmedString(args.question) || toTrimmedString(args.prompt) || toTrimmedString(args.text);
|
|
4356
|
+
const fallbackOptions = toArrayFromUnknown(args.options);
|
|
4357
|
+
const baseQuestions = rawQuestions.length > 0 ? rawQuestions : fallbackQuestion ? [
|
|
4358
|
+
{
|
|
4359
|
+
id: "question_1",
|
|
4360
|
+
header: "Question 1",
|
|
4361
|
+
question: fallbackQuestion,
|
|
4362
|
+
options: fallbackOptions,
|
|
4363
|
+
allowWriteIn: toBooleanWithDefault(args.allowWriteIn, false),
|
|
4364
|
+
writeInPlaceholder: toTrimmedString(args.writeInPlaceholder)
|
|
4365
|
+
}
|
|
4366
|
+
] : [];
|
|
4367
|
+
const questions = baseQuestions.map((entry, index) => normalizeUserInputQuestionEntry(entry, index)).filter((entry) => Boolean(entry)).slice(0, MAX_USER_INPUT_QUESTIONS);
|
|
4368
|
+
if (questions.length === 0) {
|
|
4369
|
+
throw new Error("request_user_input requires at least one valid question with options.");
|
|
4370
|
+
}
|
|
4371
|
+
return {
|
|
4372
|
+
requestId: toTrimmedString(args.requestId) || toTrimmedString(args.id) || callId,
|
|
4373
|
+
title: toTrimmedString(args.title) || DEFAULT_USER_INPUT_TITLE,
|
|
4374
|
+
instructions: toTrimmedString(args.instructions) || DEFAULT_USER_INPUT_INSTRUCTIONS,
|
|
4375
|
+
submitLabel: toTrimmedString(args.submitLabel) || "Submit",
|
|
4376
|
+
cancelLabel: toTrimmedString(args.cancelLabel) || "Cancel",
|
|
4377
|
+
allowCancel: toBooleanWithDefault(args.allowCancel, true),
|
|
4378
|
+
questions
|
|
4379
|
+
};
|
|
4380
|
+
};
|
|
4229
4381
|
var stringifyToolArgs = (value) => {
|
|
4230
4382
|
if (typeof value === "string") return value;
|
|
4231
4383
|
try {
|
|
@@ -4962,6 +5114,8 @@ var ChatInput = React14.memo(({
|
|
|
4962
5114
|
onSubmit,
|
|
4963
5115
|
onQueueSubmit,
|
|
4964
5116
|
onStop,
|
|
5117
|
+
userInputRequest = null,
|
|
5118
|
+
onCompleteUserInputRequest,
|
|
4965
5119
|
queuedPrompts = [],
|
|
4966
5120
|
onClearQueuedPrompt,
|
|
4967
5121
|
agentOptions,
|
|
@@ -4975,7 +5129,8 @@ var ChatInput = React14.memo(({
|
|
|
4975
5129
|
maxContextTokens = 8e3,
|
|
4976
5130
|
enableContextDetailView = false,
|
|
4977
5131
|
disabledSectionIds = /* @__PURE__ */ new Set(),
|
|
4978
|
-
onToggleSection
|
|
5132
|
+
onToggleSection,
|
|
5133
|
+
composerAgentModeControl
|
|
4979
5134
|
}) => {
|
|
4980
5135
|
const [inputValue, setInputValue] = useState7("");
|
|
4981
5136
|
const [dropdownOpen, setDropdownOpen] = useState7(false);
|
|
@@ -4985,6 +5140,59 @@ var ChatInput = React14.memo(({
|
|
|
4985
5140
|
const textareaRef = useRef6(null);
|
|
4986
5141
|
const containerRef = useRef6(null);
|
|
4987
5142
|
const contextPopoverRef = useRef6(null);
|
|
5143
|
+
const [userInputSelections, setUserInputSelections] = useState7({});
|
|
5144
|
+
const [userInputWriteIns, setUserInputWriteIns] = useState7({});
|
|
5145
|
+
const [userInputValidationError, setUserInputValidationError] = useState7("");
|
|
5146
|
+
const [userInputQuestionIndex, setUserInputQuestionIndex] = useState7(0);
|
|
5147
|
+
const [agentModeChipExpanded, setAgentModeChipExpanded] = useState7(false);
|
|
5148
|
+
const isAgentModeActionVisible = composerAgentModeControl !== void 0;
|
|
5149
|
+
const isAgentModeActive = Boolean(composerAgentModeControl == null ? void 0 : composerAgentModeControl.active);
|
|
5150
|
+
const isAgentModeActionDisabled = Boolean(composerAgentModeControl == null ? void 0 : composerAgentModeControl.disabled);
|
|
5151
|
+
const agentModeLabel = String((composerAgentModeControl == null ? void 0 : composerAgentModeControl.label) || "Agent").trim() || "Agent";
|
|
5152
|
+
const agentModeTitle = String((composerAgentModeControl == null ? void 0 : composerAgentModeControl.title) || "").trim() || (isAgentModeActive ? "Agent Mode active for this session" : "Enable Agent Mode");
|
|
5153
|
+
useEffect8(() => {
|
|
5154
|
+
if (isAgentModeActionVisible) return;
|
|
5155
|
+
setAgentModeChipExpanded(false);
|
|
5156
|
+
}, [isAgentModeActionVisible]);
|
|
5157
|
+
useEffect8(() => {
|
|
5158
|
+
if (!isAgentModeActive) return;
|
|
5159
|
+
setAgentModeChipExpanded(true);
|
|
5160
|
+
}, [isAgentModeActive]);
|
|
5161
|
+
const handleAgentModePillClick = useCallback2(() => {
|
|
5162
|
+
if (!isAgentModeActionVisible || isAgentModeActionDisabled) return;
|
|
5163
|
+
if (isAgentModeActive) {
|
|
5164
|
+
setAgentModeChipExpanded(true);
|
|
5165
|
+
return;
|
|
5166
|
+
}
|
|
5167
|
+
setAgentModeChipExpanded(true);
|
|
5168
|
+
if (typeof (composerAgentModeControl == null ? void 0 : composerAgentModeControl.onActivate) === "function") {
|
|
5169
|
+
composerAgentModeControl.onActivate();
|
|
5170
|
+
}
|
|
5171
|
+
}, [
|
|
5172
|
+
composerAgentModeControl,
|
|
5173
|
+
isAgentModeActionDisabled,
|
|
5174
|
+
isAgentModeActionVisible,
|
|
5175
|
+
isAgentModeActive
|
|
5176
|
+
]);
|
|
5177
|
+
useEffect8(() => {
|
|
5178
|
+
if (!userInputRequest) {
|
|
5179
|
+
setUserInputSelections({});
|
|
5180
|
+
setUserInputWriteIns({});
|
|
5181
|
+
setUserInputValidationError("");
|
|
5182
|
+
setUserInputQuestionIndex(0);
|
|
5183
|
+
return;
|
|
5184
|
+
}
|
|
5185
|
+
const nextSelections = {};
|
|
5186
|
+
const nextWriteIns = {};
|
|
5187
|
+
userInputRequest.questions.forEach((question) => {
|
|
5188
|
+
nextSelections[question.id] = "";
|
|
5189
|
+
nextWriteIns[question.id] = "";
|
|
5190
|
+
});
|
|
5191
|
+
setUserInputSelections(nextSelections);
|
|
5192
|
+
setUserInputWriteIns(nextWriteIns);
|
|
5193
|
+
setUserInputValidationError("");
|
|
5194
|
+
setUserInputQuestionIndex(0);
|
|
5195
|
+
}, [userInputRequest]);
|
|
4988
5196
|
const autoResize = useCallback2(() => {
|
|
4989
5197
|
const textarea = textareaRef.current;
|
|
4990
5198
|
if (textarea) {
|
|
@@ -5071,12 +5279,159 @@ var ChatInput = React14.memo(({
|
|
|
5071
5279
|
const hasQueuedPrompts = normalizedQueuedPrompts.length > 0;
|
|
5072
5280
|
const shouldQueueSubmission = isBusy || hasQueuedPrompts;
|
|
5073
5281
|
const showStopAction = isBusy && !hasDraft;
|
|
5282
|
+
const composerLockedByUserInput = Boolean(userInputRequest);
|
|
5283
|
+
const totalUserInputQuestions = (userInputRequest == null ? void 0 : userInputRequest.questions.length) || 0;
|
|
5284
|
+
const boundedUserInputQuestionIndex = totalUserInputQuestions > 0 ? Math.min(Math.max(userInputQuestionIndex, 0), totalUserInputQuestions - 1) : 0;
|
|
5285
|
+
const activeUserInputQuestion = totalUserInputQuestions > 0 ? (userInputRequest == null ? void 0 : userInputRequest.questions[boundedUserInputQuestionIndex]) || null : null;
|
|
5286
|
+
const isFirstUserInputQuestion = boundedUserInputQuestionIndex <= 0;
|
|
5287
|
+
const isLastUserInputQuestion = totalUserInputQuestions > 0 && boundedUserInputQuestionIndex >= totalUserInputQuestions - 1;
|
|
5288
|
+
const getQuestionAnswerState = useCallback2((question) => {
|
|
5289
|
+
const selectedValue = toTrimmedString(userInputSelections[question.id]);
|
|
5290
|
+
const writeInRaw = toTrimmedString(userInputWriteIns[question.id]);
|
|
5291
|
+
const writeIn = writeInRaw.slice(0, MAX_USER_INPUT_WRITE_IN_CHARS);
|
|
5292
|
+
const selectedOption = question.options.find((option) => option.value === selectedValue) || null;
|
|
5293
|
+
const hasAnswer = Boolean(selectedOption) || question.allowWriteIn && writeIn.length > 0;
|
|
5294
|
+
return {
|
|
5295
|
+
selectedOption,
|
|
5296
|
+
writeIn,
|
|
5297
|
+
hasAnswer
|
|
5298
|
+
};
|
|
5299
|
+
}, [userInputSelections, userInputWriteIns]);
|
|
5300
|
+
const validateUserInputQuestion = useCallback2((question) => {
|
|
5301
|
+
const answerState = getQuestionAnswerState(question);
|
|
5302
|
+
if (question.required && !answerState.hasAnswer) {
|
|
5303
|
+
setUserInputValidationError(`Please answer "${question.header}".`);
|
|
5304
|
+
return false;
|
|
5305
|
+
}
|
|
5306
|
+
return true;
|
|
5307
|
+
}, [getQuestionAnswerState]);
|
|
5308
|
+
const handleUserInputNext = useCallback2(() => {
|
|
5309
|
+
if (!activeUserInputQuestion || isLastUserInputQuestion) return;
|
|
5310
|
+
if (!validateUserInputQuestion(activeUserInputQuestion)) return;
|
|
5311
|
+
setUserInputValidationError("");
|
|
5312
|
+
setUserInputQuestionIndex((prev) => Math.min(prev + 1, totalUserInputQuestions - 1));
|
|
5313
|
+
}, [activeUserInputQuestion, isLastUserInputQuestion, totalUserInputQuestions, validateUserInputQuestion]);
|
|
5314
|
+
const handleUserInputBack = useCallback2(() => {
|
|
5315
|
+
setUserInputValidationError("");
|
|
5316
|
+
setUserInputQuestionIndex((prev) => Math.max(prev - 1, 0));
|
|
5317
|
+
}, []);
|
|
5318
|
+
const handleUserInputSubmit = useCallback2(() => {
|
|
5319
|
+
var _a, _b, _c;
|
|
5320
|
+
if (!userInputRequest || typeof onCompleteUserInputRequest !== "function") {
|
|
5321
|
+
return;
|
|
5322
|
+
}
|
|
5323
|
+
const answers = [];
|
|
5324
|
+
for (let questionIndex = 0; questionIndex < userInputRequest.questions.length; questionIndex += 1) {
|
|
5325
|
+
const question = userInputRequest.questions[questionIndex];
|
|
5326
|
+
const answerState = getQuestionAnswerState(question);
|
|
5327
|
+
if (question.required && !answerState.hasAnswer) {
|
|
5328
|
+
setUserInputQuestionIndex(questionIndex);
|
|
5329
|
+
setUserInputValidationError(`Please answer "${question.header}".`);
|
|
5330
|
+
return;
|
|
5331
|
+
}
|
|
5332
|
+
answers.push({
|
|
5333
|
+
id: question.id,
|
|
5334
|
+
header: question.header,
|
|
5335
|
+
question: question.question,
|
|
5336
|
+
selectedOptionValue: ((_a = answerState.selectedOption) == null ? void 0 : _a.value) || null,
|
|
5337
|
+
selectedOptionLabel: ((_b = answerState.selectedOption) == null ? void 0 : _b.label) || null,
|
|
5338
|
+
writeIn: answerState.writeIn || null,
|
|
5339
|
+
answer: answerState.writeIn || ((_c = answerState.selectedOption) == null ? void 0 : _c.label) || ""
|
|
5340
|
+
});
|
|
5341
|
+
}
|
|
5342
|
+
setUserInputValidationError("");
|
|
5343
|
+
onCompleteUserInputRequest({
|
|
5344
|
+
status: "submitted",
|
|
5345
|
+
requestId: userInputRequest.requestId,
|
|
5346
|
+
answers
|
|
5347
|
+
});
|
|
5348
|
+
}, [getQuestionAnswerState, onCompleteUserInputRequest, userInputRequest]);
|
|
5349
|
+
const handleUserInputCancel = useCallback2(() => {
|
|
5350
|
+
if (!userInputRequest || typeof onCompleteUserInputRequest !== "function") {
|
|
5351
|
+
return;
|
|
5352
|
+
}
|
|
5353
|
+
onCompleteUserInputRequest({
|
|
5354
|
+
status: "cancelled",
|
|
5355
|
+
requestId: userInputRequest.requestId,
|
|
5356
|
+
cancelledBy: "user"
|
|
5357
|
+
});
|
|
5358
|
+
}, [onCompleteUserInputRequest, userInputRequest]);
|
|
5074
5359
|
return /* @__PURE__ */ React14.createElement(
|
|
5075
5360
|
"div",
|
|
5076
5361
|
{
|
|
5077
5362
|
className: `ai-chat-panel__input-container ${dropdownOpen ? "ai-chat-panel__input-container--dropdown-open" : ""}`,
|
|
5078
5363
|
ref: containerRef
|
|
5079
5364
|
},
|
|
5365
|
+
userInputRequest && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover", role: "dialog", "aria-live": "polite", "aria-label": userInputRequest.title }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__header" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__title" }, userInputRequest.title), /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__header-meta" }, totalUserInputQuestions > 1 && /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__progress" }, boundedUserInputQuestionIndex + 1, " of ", totalUserInputQuestions), userInputRequest.allowCancel && /* @__PURE__ */ React14.createElement(
|
|
5366
|
+
"button",
|
|
5367
|
+
{
|
|
5368
|
+
type: "button",
|
|
5369
|
+
className: "ai-chat-user-input-popover__cancel-inline",
|
|
5370
|
+
onClick: handleUserInputCancel
|
|
5371
|
+
},
|
|
5372
|
+
userInputRequest.cancelLabel
|
|
5373
|
+
))), userInputRequest.instructions && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__instructions" }, userInputRequest.instructions), activeUserInputQuestion && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__question" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__question-header" }, /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__question-index" }, boundedUserInputQuestionIndex + 1), /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__question-title" }, activeUserInputQuestion.header)), /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__question-text" }, activeUserInputQuestion.question), /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__options" }, activeUserInputQuestion.options.map((option) => /* @__PURE__ */ React14.createElement("label", { key: `${activeUserInputQuestion.id}:${option.value}`, className: "ai-chat-user-input-popover__option" }, /* @__PURE__ */ React14.createElement(
|
|
5374
|
+
"input",
|
|
5375
|
+
{
|
|
5376
|
+
type: "radio",
|
|
5377
|
+
name: `user-input-${activeUserInputQuestion.id}`,
|
|
5378
|
+
value: option.value,
|
|
5379
|
+
checked: (userInputSelections[activeUserInputQuestion.id] || "") === option.value,
|
|
5380
|
+
onChange: () => {
|
|
5381
|
+
setUserInputValidationError("");
|
|
5382
|
+
setUserInputSelections((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
5383
|
+
[activeUserInputQuestion.id]: option.value
|
|
5384
|
+
}));
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
), /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__option-content" }, /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__option-label" }, option.label), option.description ? /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-user-input-popover__option-description" }, option.description) : null)))), activeUserInputQuestion.allowWriteIn && /* @__PURE__ */ React14.createElement(
|
|
5388
|
+
"textarea",
|
|
5389
|
+
{
|
|
5390
|
+
className: "ai-chat-user-input-popover__writein",
|
|
5391
|
+
placeholder: activeUserInputQuestion.writeInPlaceholder,
|
|
5392
|
+
value: userInputWriteIns[activeUserInputQuestion.id] || "",
|
|
5393
|
+
onChange: (event) => {
|
|
5394
|
+
const nextValue = event.target.value.slice(0, MAX_USER_INPUT_WRITE_IN_CHARS);
|
|
5395
|
+
setUserInputValidationError("");
|
|
5396
|
+
setUserInputWriteIns((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
5397
|
+
[activeUserInputQuestion.id]: nextValue
|
|
5398
|
+
}));
|
|
5399
|
+
},
|
|
5400
|
+
rows: 2
|
|
5401
|
+
}
|
|
5402
|
+
)), userInputValidationError ? /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__error" }, userInputValidationError) : null, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__actions" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__actions-left" }, userInputRequest.allowCancel && /* @__PURE__ */ React14.createElement(
|
|
5403
|
+
"button",
|
|
5404
|
+
{
|
|
5405
|
+
type: "button",
|
|
5406
|
+
className: "ai-chat-user-input-popover__button ai-chat-user-input-popover__button--secondary",
|
|
5407
|
+
onClick: handleUserInputCancel
|
|
5408
|
+
},
|
|
5409
|
+
userInputRequest.cancelLabel
|
|
5410
|
+
)), /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-user-input-popover__actions-right" }, !isFirstUserInputQuestion && /* @__PURE__ */ React14.createElement(
|
|
5411
|
+
"button",
|
|
5412
|
+
{
|
|
5413
|
+
type: "button",
|
|
5414
|
+
className: "ai-chat-user-input-popover__button ai-chat-user-input-popover__button--secondary",
|
|
5415
|
+
onClick: handleUserInputBack
|
|
5416
|
+
},
|
|
5417
|
+
"Back"
|
|
5418
|
+
), isLastUserInputQuestion ? /* @__PURE__ */ React14.createElement(
|
|
5419
|
+
"button",
|
|
5420
|
+
{
|
|
5421
|
+
type: "button",
|
|
5422
|
+
className: "ai-chat-user-input-popover__button ai-chat-user-input-popover__button--primary",
|
|
5423
|
+
onClick: handleUserInputSubmit
|
|
5424
|
+
},
|
|
5425
|
+
userInputRequest.submitLabel
|
|
5426
|
+
) : /* @__PURE__ */ React14.createElement(
|
|
5427
|
+
"button",
|
|
5428
|
+
{
|
|
5429
|
+
type: "button",
|
|
5430
|
+
className: "ai-chat-user-input-popover__button ai-chat-user-input-popover__button--primary",
|
|
5431
|
+
onClick: handleUserInputNext
|
|
5432
|
+
},
|
|
5433
|
+
"Next"
|
|
5434
|
+
)))),
|
|
5080
5435
|
hasQueuedPrompts && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-queued-prompts" }, normalizedQueuedPrompts.map((queuedPrompt, index) => /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-queued-prompt", title: queuedPrompt, key: `${index}-${queuedPrompt}` }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-queued-prompt__content" }, /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-queued-prompt__label" }, index === 0 ? "Queued next" : `Queued ${index + 1}`), /* @__PURE__ */ React14.createElement("span", { className: "ai-chat-queued-prompt__text" }, queuedPrompt)), /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-queued-prompt__actions" }, /* @__PURE__ */ React14.createElement(
|
|
5081
5436
|
"button",
|
|
5082
5437
|
{
|
|
@@ -5100,8 +5455,9 @@ var ChatInput = React14.memo(({
|
|
|
5100
5455
|
{
|
|
5101
5456
|
ref: textareaRef,
|
|
5102
5457
|
className: "ai-chat-input",
|
|
5103
|
-
placeholder,
|
|
5458
|
+
placeholder: composerLockedByUserInput ? "Answer the question above to continue\u2026" : placeholder,
|
|
5104
5459
|
value: inputValue,
|
|
5460
|
+
disabled: composerLockedByUserInput,
|
|
5105
5461
|
onChange: (e) => {
|
|
5106
5462
|
setInputValue(e.target.value);
|
|
5107
5463
|
setTimeout(autoResize, 0);
|
|
@@ -5115,7 +5471,7 @@ var ChatInput = React14.memo(({
|
|
|
5115
5471
|
rows: 1
|
|
5116
5472
|
}
|
|
5117
5473
|
)),
|
|
5118
|
-
/* @__PURE__ */ React14.createElement("div", { className: "ai-chat-panel__input-footer" }, agentOptions.length > 0 ? /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-agent-selector" }, /* @__PURE__ */ React14.createElement(
|
|
5474
|
+
/* @__PURE__ */ React14.createElement("div", { className: "ai-chat-panel__input-footer" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-input-footer__left" }, agentOptions.length > 0 ? /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-agent-selector" }, /* @__PURE__ */ React14.createElement(
|
|
5119
5475
|
"button",
|
|
5120
5476
|
{
|
|
5121
5477
|
className: "ai-chat-agent-selector__trigger",
|
|
@@ -5132,7 +5488,20 @@ var ChatInput = React14.memo(({
|
|
|
5132
5488
|
) : /* @__PURE__ */ React14.createElement(AgentIcon, null),
|
|
5133
5489
|
/* @__PURE__ */ React14.createElement("span", { className: "ai-chat-agent-selector__label" }, agentsLoading ? "Loading..." : currentAgentLabel || "Select agent"),
|
|
5134
5490
|
dropdownOpen ? /* @__PURE__ */ React14.createElement(ChevronUpIcon, null) : /* @__PURE__ */ React14.createElement(ChevronDownIcon, null)
|
|
5135
|
-
)) :
|
|
5491
|
+
)) : null, isAgentModeActionVisible && /* @__PURE__ */ React14.createElement(
|
|
5492
|
+
"button",
|
|
5493
|
+
{
|
|
5494
|
+
className: `ai-chat-agent-mode-trigger ${agentModeChipExpanded ? "ai-chat-agent-mode-trigger--expanded" : ""} ${isAgentModeActive ? "ai-chat-agent-mode-trigger--active" : ""}`,
|
|
5495
|
+
onClick: handleAgentModePillClick,
|
|
5496
|
+
type: "button",
|
|
5497
|
+
title: agentModeTitle,
|
|
5498
|
+
"aria-label": isAgentModeActive ? "Agent active" : "Enable Agent Mode",
|
|
5499
|
+
"aria-pressed": isAgentModeActive,
|
|
5500
|
+
disabled: isAgentModeActionDisabled
|
|
5501
|
+
},
|
|
5502
|
+
/* @__PURE__ */ React14.createElement("span", { className: "ai-chat-agent-mode-trigger__icon", "aria-hidden": "true" }, /* @__PURE__ */ React14.createElement(AgentIcon, null)),
|
|
5503
|
+
/* @__PURE__ */ React14.createElement("span", { className: "ai-chat-agent-mode-trigger__label" }, agentModeLabel)
|
|
5504
|
+
), agentOptions.length === 0 && !isAgentModeActionVisible ? /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-panel__input-footer-spacer" }) : null), contextSections.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-context-pill-wrapper" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-context-pill-anchor" }, /* @__PURE__ */ React14.createElement(
|
|
5136
5505
|
"button",
|
|
5137
5506
|
{
|
|
5138
5507
|
className: `ai-chat-context-pill ${contextViewerOpen ? "ai-chat-context-pill--active" : ""} ${isOverLimit ? "ai-chat-context-pill--warning" : ""}`,
|
|
@@ -5267,13 +5636,13 @@ var ChatInput = React14.memo(({
|
|
|
5267
5636
|
/* @__PURE__ */ React14.createElement("pre", { className: "ai-chat-context-popover__detail-content" }, /* @__PURE__ */ React14.createElement("code", null, isRawSection ? section.rawData : getStructuredContent(section)))
|
|
5268
5637
|
);
|
|
5269
5638
|
})))
|
|
5270
|
-
)), /* @__PURE__ */ React14.createElement(
|
|
5639
|
+
))), /* @__PURE__ */ React14.createElement(
|
|
5271
5640
|
"button",
|
|
5272
5641
|
{
|
|
5273
|
-
className: `ai-chat-send-button ${!showStopAction && !hasDraft ? "ai-chat-send-button--disabled" : ""} ${showStopAction ? "ai-chat-send-button--stop" : ""}`,
|
|
5642
|
+
className: `ai-chat-send-button ${!showStopAction && (!hasDraft || composerLockedByUserInput) ? "ai-chat-send-button--disabled" : ""} ${showStopAction ? "ai-chat-send-button--stop" : ""}`,
|
|
5274
5643
|
onClick: () => showStopAction ? onStop() : handleSubmit(),
|
|
5275
|
-
disabled: !showStopAction && !hasDraft,
|
|
5276
|
-
title: showStopAction ? "Stop response" : shouldQueueSubmission ? "Queue prompt" : "Send prompt"
|
|
5644
|
+
disabled: !showStopAction && !hasDraft || !showStopAction && composerLockedByUserInput,
|
|
5645
|
+
title: showStopAction ? "Stop response" : composerLockedByUserInput ? "Answer the question above to continue" : shouldQueueSubmission ? "Queue prompt" : "Send prompt"
|
|
5277
5646
|
},
|
|
5278
5647
|
showStopAction ? /* @__PURE__ */ React14.createElement(StopIcon, null) : /* @__PURE__ */ React14.createElement(ArrowUpIcon, null)
|
|
5279
5648
|
)),
|
|
@@ -5350,6 +5719,8 @@ var AIChatPanel = ({
|
|
|
5350
5719
|
onToggleSection: propOnToggleSection,
|
|
5351
5720
|
onConversationCreated,
|
|
5352
5721
|
onBeforeSend,
|
|
5722
|
+
compactContext,
|
|
5723
|
+
compactionPreserveTurns = DEFAULT_COMPACTION_PRESERVE_TURNS,
|
|
5353
5724
|
// UI Customization Props
|
|
5354
5725
|
cssUrl,
|
|
5355
5726
|
markdownClass,
|
|
@@ -5369,7 +5740,8 @@ var AIChatPanel = ({
|
|
|
5369
5740
|
// Customer Email Capture Props
|
|
5370
5741
|
customerEmailCaptureMode = "HIDE",
|
|
5371
5742
|
customerEmailCapturePlaceholder = "Please enter your email...",
|
|
5372
|
-
toolStatusLabelFormatter
|
|
5743
|
+
toolStatusLabelFormatter,
|
|
5744
|
+
composerAgentModeControl
|
|
5373
5745
|
}) => {
|
|
5374
5746
|
var _a;
|
|
5375
5747
|
const publicAPIUrl = "https://api.llmasaservice.io";
|
|
@@ -5395,6 +5767,7 @@ var AIChatPanel = ({
|
|
|
5395
5767
|
const [copiedCallId, setCopiedCallId] = useState7(null);
|
|
5396
5768
|
const [feedbackCallId, setFeedbackCallId] = useState7(null);
|
|
5397
5769
|
const [error, setError] = useState7(null);
|
|
5770
|
+
const [compactionNotice, setCompactionNotice] = useState7(null);
|
|
5398
5771
|
const lastProcessedErrorRef = useRef6(null);
|
|
5399
5772
|
const [emailSent, setEmailSent] = useState7(false);
|
|
5400
5773
|
const [isToolInfoModalOpen, setIsToolInfoModalOpen] = useState7(false);
|
|
@@ -5414,6 +5787,9 @@ var AIChatPanel = ({
|
|
|
5414
5787
|
const [toolsFetchError, setToolsFetchError] = useState7(false);
|
|
5415
5788
|
const [resolvedMcpServers, setResolvedMcpServers] = useState7(mcpServers || []);
|
|
5416
5789
|
const [activeToolCalls, setActiveToolCalls] = useState7([]);
|
|
5790
|
+
const [pendingUserInputRequest, setPendingUserInputRequest] = useState7(null);
|
|
5791
|
+
const pendingUserInputRequestRef = useRef6(null);
|
|
5792
|
+
const pendingUserInputResolverRef = useRef6(null);
|
|
5417
5793
|
const normalizeToolName = useCallback2((toolName) => {
|
|
5418
5794
|
return String(toolName != null ? toolName : "").trim().toLowerCase();
|
|
5419
5795
|
}, []);
|
|
@@ -5426,6 +5802,32 @@ var AIChatPanel = ({
|
|
|
5426
5802
|
},
|
|
5427
5803
|
[normalizeToolName]
|
|
5428
5804
|
);
|
|
5805
|
+
const completePendingUserInputRequest = useCallback2((payload) => {
|
|
5806
|
+
const resolver = pendingUserInputResolverRef.current;
|
|
5807
|
+
pendingUserInputResolverRef.current = null;
|
|
5808
|
+
pendingUserInputRequestRef.current = null;
|
|
5809
|
+
setPendingUserInputRequest(null);
|
|
5810
|
+
if (resolver) {
|
|
5811
|
+
resolver(payload);
|
|
5812
|
+
}
|
|
5813
|
+
}, []);
|
|
5814
|
+
useEffect8(() => {
|
|
5815
|
+
pendingUserInputRequestRef.current = pendingUserInputRequest;
|
|
5816
|
+
}, [pendingUserInputRequest]);
|
|
5817
|
+
useEffect8(() => {
|
|
5818
|
+
return () => {
|
|
5819
|
+
var _a2;
|
|
5820
|
+
const resolver = pendingUserInputResolverRef.current;
|
|
5821
|
+
if (!resolver) return;
|
|
5822
|
+
pendingUserInputResolverRef.current = null;
|
|
5823
|
+
const pendingRequestId = ((_a2 = pendingUserInputRequestRef.current) == null ? void 0 : _a2.requestId) || "request_user_input";
|
|
5824
|
+
resolver({
|
|
5825
|
+
status: "cancelled",
|
|
5826
|
+
requestId: pendingRequestId,
|
|
5827
|
+
cancelledBy: "unmount"
|
|
5828
|
+
});
|
|
5829
|
+
};
|
|
5830
|
+
}, []);
|
|
5429
5831
|
const alwaysApprovedToolsStorageKey = useMemo2(() => {
|
|
5430
5832
|
const customerId = (customer == null ? void 0 : customer.customer_id) || (customer == null ? void 0 : customer.id) || (customer == null ? void 0 : customer.customer_user_email) || "anonymous";
|
|
5431
5833
|
const agentIdForScope = currentAgentId || agent || "default";
|
|
@@ -6055,6 +6457,42 @@ var AIChatPanel = ({
|
|
|
6055
6457
|
if (hasInFlightTurnWork()) return;
|
|
6056
6458
|
turnLockRef.current = false;
|
|
6057
6459
|
}, [hasInFlightTurnWork]);
|
|
6460
|
+
const runRequestUserInputTool = useCallback2(
|
|
6461
|
+
(toolCall) => __async(void 0, null, function* () {
|
|
6462
|
+
const normalizedToolName = normalizeToolName(toolCall.toolName);
|
|
6463
|
+
if (!USER_INPUT_TOOL_NAMES.has(normalizedToolName)) {
|
|
6464
|
+
throw new Error(`Unsupported user input tool: ${toolCall.toolName}`);
|
|
6465
|
+
}
|
|
6466
|
+
if (pendingUserInputResolverRef.current || pendingUserInputRequestRef.current) {
|
|
6467
|
+
throw new Error("A user input request is already pending. Wait for completion before requesting another.");
|
|
6468
|
+
}
|
|
6469
|
+
const request = normalizeUserInputRequest(
|
|
6470
|
+
isObjectRecord(toolCall.args) ? toolCall.args : {},
|
|
6471
|
+
toolCall.callId || toolCall.toolName
|
|
6472
|
+
);
|
|
6473
|
+
pendingUserInputRequestRef.current = request;
|
|
6474
|
+
setPendingUserInputRequest(request);
|
|
6475
|
+
const completion = yield new Promise((resolve) => {
|
|
6476
|
+
pendingUserInputResolverRef.current = resolve;
|
|
6477
|
+
});
|
|
6478
|
+
if (completion.status === "cancelled") {
|
|
6479
|
+
return {
|
|
6480
|
+
status: "cancelled",
|
|
6481
|
+
requestId: request.requestId,
|
|
6482
|
+
cancelledBy: completion.cancelledBy || "user",
|
|
6483
|
+
answers: []
|
|
6484
|
+
};
|
|
6485
|
+
}
|
|
6486
|
+
const answers = Array.isArray(completion.answers) ? completion.answers : [];
|
|
6487
|
+
return {
|
|
6488
|
+
status: "ok",
|
|
6489
|
+
requestId: request.requestId,
|
|
6490
|
+
answers,
|
|
6491
|
+
answeredCount: answers.length
|
|
6492
|
+
};
|
|
6493
|
+
}),
|
|
6494
|
+
[normalizeToolName]
|
|
6495
|
+
);
|
|
6058
6496
|
const processGivenToolRequests = useCallback2(
|
|
6059
6497
|
(requests) => __async(void 0, null, function* () {
|
|
6060
6498
|
var _a2, _b, _c;
|
|
@@ -6309,6 +6747,29 @@ ${traceSummary}` : traceSummary;
|
|
|
6309
6747
|
var _a3, _b2, _c2, _d, _e, _f, _g;
|
|
6310
6748
|
const mcpTool = toolList.find((tool) => tool.name === toolCall.toolName) || null;
|
|
6311
6749
|
const localExecutor = localToolExecutors && typeof localToolExecutors[toolCall.toolName] === "function" ? localToolExecutors[toolCall.toolName] : null;
|
|
6750
|
+
const normalizedToolName = normalizeToolName(toolCall.toolName);
|
|
6751
|
+
if (USER_INPUT_TOOL_NAMES.has(normalizedToolName)) {
|
|
6752
|
+
try {
|
|
6753
|
+
const requestResult = yield runRequestUserInputTool({
|
|
6754
|
+
toolName: toolCall.toolName,
|
|
6755
|
+
callId: toolCall.callId,
|
|
6756
|
+
args: toolCall.args
|
|
6757
|
+
});
|
|
6758
|
+
return {
|
|
6759
|
+
tool_call_id: toolCall.callId,
|
|
6760
|
+
tool_name: toolCall.toolName,
|
|
6761
|
+
result: JSON.stringify(requestResult),
|
|
6762
|
+
isError: false
|
|
6763
|
+
};
|
|
6764
|
+
} catch (error2) {
|
|
6765
|
+
return {
|
|
6766
|
+
tool_call_id: toolCall.callId,
|
|
6767
|
+
tool_name: toolCall.toolName,
|
|
6768
|
+
result: error2 instanceof Error ? error2.message : `Unhandled error calling ${toolCall.toolName}`,
|
|
6769
|
+
isError: true
|
|
6770
|
+
};
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6312
6773
|
if (localExecutor) {
|
|
6313
6774
|
try {
|
|
6314
6775
|
const localResult = yield localExecutor(toolCall.args, {
|
|
@@ -6625,6 +7086,8 @@ ${traceSummary}` : traceSummary;
|
|
|
6625
7086
|
idle,
|
|
6626
7087
|
stop,
|
|
6627
7088
|
lastController,
|
|
7089
|
+
normalizeToolName,
|
|
7090
|
+
runRequestUserInputTool,
|
|
6628
7091
|
waitForStreamIdle,
|
|
6629
7092
|
releaseTurnLockIfSettled
|
|
6630
7093
|
]
|
|
@@ -7020,6 +7483,7 @@ ${traceSummary}` : traceSummary;
|
|
|
7020
7483
|
hasAutoCollapsedRef.current = false;
|
|
7021
7484
|
prevBlockCountRef.current = 0;
|
|
7022
7485
|
setError(null);
|
|
7486
|
+
setCompactionNotice(null);
|
|
7023
7487
|
setUserHasScrolled(false);
|
|
7024
7488
|
prevResponseLengthRef.current = 0;
|
|
7025
7489
|
setResponse("");
|
|
@@ -7038,144 +7502,232 @@ ${traceSummary}` : traceSummary;
|
|
|
7038
7502
|
setTimeout(() => {
|
|
7039
7503
|
scrollToBottom(true);
|
|
7040
7504
|
}, 0);
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
const
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7505
|
+
void (() => __async(void 0, null, function* () {
|
|
7506
|
+
var _a2, _b;
|
|
7507
|
+
try {
|
|
7508
|
+
console.log("AIChatPanel.continueChat - about to call ensureConversation");
|
|
7509
|
+
const convId = yield ensureConversation();
|
|
7510
|
+
console.log("AIChatPanel.continueChat - ensureConversation resolved with:", convId);
|
|
7511
|
+
const historyForCall = latestHistoryRef.current || {};
|
|
7512
|
+
const messagesAndHistory = [];
|
|
7513
|
+
Object.entries(historyForCall).forEach(([historyPrompt, historyEntry]) => {
|
|
7514
|
+
if (historyPrompt === promptKey) return;
|
|
7515
|
+
const promptForHistory = normalizeHistoryPromptForContext(historyPrompt);
|
|
7516
|
+
const assistantContextContent = buildAssistantContextContent(historyPrompt, historyEntry);
|
|
7517
|
+
messagesAndHistory.push({ role: "user", content: promptForHistory });
|
|
7518
|
+
messagesAndHistory.push({ role: "assistant", content: assistantContextContent });
|
|
7519
|
+
});
|
|
7520
|
+
let fullPromptToSend = promptToSend;
|
|
7521
|
+
if (messagesAndHistory.length === 0 && promptTemplate) {
|
|
7522
|
+
fullPromptToSend = promptTemplate.replace("{{prompt}}", fullPromptToSend);
|
|
7523
|
+
}
|
|
7524
|
+
const newController = new AbortController();
|
|
7525
|
+
setLastController(newController);
|
|
7526
|
+
if (onBeforeSend) {
|
|
7527
|
+
try {
|
|
7528
|
+
yield Promise.resolve(
|
|
7529
|
+
onBeforeSend({
|
|
7530
|
+
prompt: promptToSend,
|
|
7531
|
+
conversationId: convId || null,
|
|
7532
|
+
agentId: agent,
|
|
7533
|
+
service,
|
|
7534
|
+
messages: messagesAndHistory
|
|
7535
|
+
})
|
|
7536
|
+
);
|
|
7537
|
+
} catch (error2) {
|
|
7538
|
+
console.warn("[AIChatPanel] onBeforeSend callback failed:", error2);
|
|
7539
|
+
}
|
|
7540
|
+
}
|
|
7541
|
+
const warnRatio = toBoundedRatio(DEFAULT_CONTEXT_WARN_RATIO, DEFAULT_CONTEXT_WARN_RATIO);
|
|
7542
|
+
const compactRatio = toBoundedRatio(DEFAULT_CONTEXT_COMPACT_RATIO, DEFAULT_CONTEXT_COMPACT_RATIO);
|
|
7543
|
+
const targetRatio = toBoundedRatio(DEFAULT_CONTEXT_TARGET_RATIO, DEFAULT_CONTEXT_TARGET_RATIO);
|
|
7544
|
+
const maxTokens = Math.max(1, Number.isFinite(Number(maxContextTokens)) ? Math.floor(Number(maxContextTokens)) : 8e3);
|
|
7545
|
+
const dataEntries = dataWithExtras();
|
|
7546
|
+
const projectedBefore = estimateTokensFromText(fullPromptToSend) + estimateTokensFromMessages(messagesAndHistory) + Math.max(Number(totalContextTokens) || 0, estimateTokensFromData(dataEntries));
|
|
7547
|
+
const warnThreshold = Math.floor(maxTokens * warnRatio);
|
|
7548
|
+
const compactThreshold = Math.floor(maxTokens * compactRatio);
|
|
7549
|
+
const targetThreshold = Math.floor(maxTokens * targetRatio);
|
|
7550
|
+
const preserveTurnsForCompaction = Number.isFinite(Number(compactionPreserveTurns)) && Number(compactionPreserveTurns) > 0 ? Math.floor(Number(compactionPreserveTurns)) : DEFAULT_COMPACTION_PRESERVE_TURNS;
|
|
7551
|
+
const canDropOlderTurns = buildFallbackWindowMessages(messagesAndHistory, preserveTurnsForCompaction).length < messagesAndHistory.length;
|
|
7552
|
+
let sendPrompt = fullPromptToSend;
|
|
7553
|
+
let sendMessages = messagesAndHistory;
|
|
7554
|
+
if (projectedBefore >= warnThreshold && projectedBefore < compactThreshold) {
|
|
7555
|
+
const nearLimitMessage = "Context is approaching the configured limit. A later turn may auto-compact.";
|
|
7556
|
+
setCompactionNotice({
|
|
7557
|
+
level: "warning",
|
|
7558
|
+
message: nearLimitMessage
|
|
7559
|
+
});
|
|
7560
|
+
}
|
|
7561
|
+
if (compactContext && projectedBefore >= compactThreshold && canDropOlderTurns) {
|
|
7562
|
+
setCompactionNotice({
|
|
7563
|
+
level: "info",
|
|
7564
|
+
message: "Automatically compacting context"
|
|
7565
|
+
});
|
|
7566
|
+
const compactionInput = {
|
|
7567
|
+
prompt: fullPromptToSend,
|
|
7063
7568
|
conversationId: convId || null,
|
|
7064
7569
|
agentId: agent,
|
|
7065
7570
|
service,
|
|
7066
|
-
messages: messagesAndHistory
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
// stream
|
|
7081
|
-
true,
|
|
7082
|
-
// includeHistory
|
|
7083
|
-
service,
|
|
7084
|
-
// group_id from agent config
|
|
7085
|
-
convId,
|
|
7086
|
-
// Use the conversation ID from ensureConversation
|
|
7087
|
-
newController,
|
|
7088
|
-
void 0,
|
|
7089
|
-
// onComplete
|
|
7090
|
-
(errorMsg) => {
|
|
7091
|
-
console.log("[AIChatPanel] Error callback triggered:", errorMsg);
|
|
7092
|
-
const isAbortError = errorMsg.toLowerCase().includes("abort") || errorMsg.toLowerCase().includes("canceled") || errorMsg.toLowerCase().includes("cancelled");
|
|
7093
|
-
if (isAbortError) {
|
|
7094
|
-
if (suppressAbortHistoryUpdateRef.current) {
|
|
7095
|
-
setIsLoading(false);
|
|
7096
|
-
releaseTurnLockIfSettled();
|
|
7097
|
-
return;
|
|
7571
|
+
messages: messagesAndHistory,
|
|
7572
|
+
data: dataEntries,
|
|
7573
|
+
maxContextTokens: maxTokens,
|
|
7574
|
+
totalContextTokens: Number(totalContextTokens) || 0,
|
|
7575
|
+
warnRatio,
|
|
7576
|
+
compactRatio,
|
|
7577
|
+
targetRatio,
|
|
7578
|
+
preserveTurns: preserveTurnsForCompaction,
|
|
7579
|
+
projectedTokens: {
|
|
7580
|
+
projectedBefore,
|
|
7581
|
+
projectedAfter: projectedBefore,
|
|
7582
|
+
warnThreshold,
|
|
7583
|
+
compactThreshold,
|
|
7584
|
+
targetThreshold
|
|
7098
7585
|
}
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7586
|
+
};
|
|
7587
|
+
try {
|
|
7588
|
+
const compactResult = yield Promise.resolve(compactContext(compactionInput));
|
|
7589
|
+
if (compactResult && typeof compactResult === "object") {
|
|
7590
|
+
if (typeof compactResult.prompt === "string" && compactResult.prompt.trim()) {
|
|
7591
|
+
sendPrompt = compactResult.prompt;
|
|
7592
|
+
}
|
|
7593
|
+
if (Array.isArray(compactResult.messages)) {
|
|
7594
|
+
sendMessages = compactResult.messages;
|
|
7595
|
+
}
|
|
7596
|
+
if (compactResult.action === "compacted") {
|
|
7597
|
+
const usageBefore = Number((_a2 = compactResult.tokenUsage) == null ? void 0 : _a2.projectedBefore);
|
|
7598
|
+
const usageAfter = Number((_b = compactResult.tokenUsage) == null ? void 0 : _b.projectedAfter);
|
|
7599
|
+
const hasUsageNumbers = Number.isFinite(usageBefore) && Number.isFinite(usageAfter);
|
|
7600
|
+
const compactedMessage = hasUsageNumbers ? `Context compacted for this send (${formatTokenCount(usageBefore)} -> ${formatTokenCount(usageAfter)} tokens).` : "Older turns were compacted to keep this thread within context limits.";
|
|
7601
|
+
setCompactionNotice({
|
|
7602
|
+
level: "success",
|
|
7603
|
+
message: compactResult.warning || compactedMessage
|
|
7108
7604
|
});
|
|
7109
|
-
})
|
|
7605
|
+
} else if (compactResult.action === "fallback_window") {
|
|
7606
|
+
setCompactionNotice({
|
|
7607
|
+
level: "warning",
|
|
7608
|
+
message: compactResult.warning || "Compaction fallback applied. Sending only the most recent turns."
|
|
7609
|
+
});
|
|
7610
|
+
} else {
|
|
7611
|
+
setCompactionNotice(null);
|
|
7612
|
+
}
|
|
7110
7613
|
}
|
|
7111
|
-
}
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
|
|
7614
|
+
} catch (error2) {
|
|
7615
|
+
console.warn("[AIChatPanel] compactContext failed, applying local fallback window", error2);
|
|
7616
|
+
sendMessages = buildFallbackWindowMessages(messagesAndHistory, preserveTurnsForCompaction);
|
|
7617
|
+
setCompactionNotice({
|
|
7618
|
+
level: "warning",
|
|
7619
|
+
message: "Compaction service unavailable. Sending a reduced recent-window context."
|
|
7115
7620
|
});
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7621
|
+
}
|
|
7622
|
+
}
|
|
7623
|
+
send(
|
|
7624
|
+
sendPrompt,
|
|
7625
|
+
sendMessages,
|
|
7626
|
+
[
|
|
7627
|
+
...dataEntries,
|
|
7628
|
+
{ key: "--messages", data: sendMessages.length.toString() }
|
|
7629
|
+
],
|
|
7630
|
+
true,
|
|
7631
|
+
// stream
|
|
7632
|
+
true,
|
|
7633
|
+
// includeHistory
|
|
7634
|
+
service,
|
|
7635
|
+
// group_id from agent config
|
|
7636
|
+
convId,
|
|
7637
|
+
// Use the conversation ID from ensureConversation
|
|
7638
|
+
newController,
|
|
7639
|
+
void 0,
|
|
7640
|
+
// onComplete
|
|
7641
|
+
(errorMsg) => {
|
|
7642
|
+
console.log("[AIChatPanel] Error callback triggered:", errorMsg);
|
|
7643
|
+
const isAbortError = errorMsg.toLowerCase().includes("abort") || errorMsg.toLowerCase().includes("canceled") || errorMsg.toLowerCase().includes("cancelled");
|
|
7644
|
+
if (isAbortError) {
|
|
7645
|
+
if (suppressAbortHistoryUpdateRef.current) {
|
|
7646
|
+
setIsLoading(false);
|
|
7647
|
+
releaseTurnLockIfSettled();
|
|
7648
|
+
return;
|
|
7649
|
+
}
|
|
7650
|
+
console.log("[AIChatPanel] Request was aborted by user");
|
|
7651
|
+
if (promptKey) {
|
|
7652
|
+
setHistory((prev) => {
|
|
7653
|
+
const existingEntry = prev[promptKey] || { content: "", callId: "" };
|
|
7654
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7655
|
+
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7656
|
+
content: "Response canceled",
|
|
7657
|
+
callId: lastCallId || existingEntry.callId || ""
|
|
7658
|
+
})
|
|
7659
|
+
});
|
|
7124
7660
|
});
|
|
7661
|
+
}
|
|
7662
|
+
} else if (errorMsg.includes("413") || errorMsg.toLowerCase().includes("content too large")) {
|
|
7663
|
+
setError({
|
|
7664
|
+
message: "The context is too large to process. Please start a new conversation or reduce the amount of context.",
|
|
7665
|
+
code: "413"
|
|
7125
7666
|
});
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
return __spreadProps(__spreadValues({}, prev), {
|
|
7136
|
-
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7137
|
-
content: `Error: ${errorMsg}`,
|
|
7138
|
-
callId: lastCallId || existingEntry.callId || ""
|
|
7139
|
-
})
|
|
7667
|
+
if (promptKey) {
|
|
7668
|
+
setHistory((prev) => {
|
|
7669
|
+
const existingEntry = prev[promptKey] || { content: "", callId: "" };
|
|
7670
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7671
|
+
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7672
|
+
content: `Error: ${errorMsg}`,
|
|
7673
|
+
callId: lastCallId || existingEntry.callId || ""
|
|
7674
|
+
})
|
|
7675
|
+
});
|
|
7140
7676
|
});
|
|
7677
|
+
}
|
|
7678
|
+
} else if (errorMsg.toLowerCase().includes("network error") || errorMsg.toLowerCase().includes("fetch")) {
|
|
7679
|
+
setError({
|
|
7680
|
+
message: "Network error. Please check your connection and try again.",
|
|
7681
|
+
code: "NETWORK_ERROR"
|
|
7141
7682
|
});
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
return __spreadProps(__spreadValues({}, prev), {
|
|
7152
|
-
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7153
|
-
content: `Error: ${errorMsg}`,
|
|
7154
|
-
callId: lastCallId || existingEntry.callId || ""
|
|
7155
|
-
})
|
|
7683
|
+
if (promptKey) {
|
|
7684
|
+
setHistory((prev) => {
|
|
7685
|
+
const existingEntry = prev[promptKey] || { content: "", callId: "" };
|
|
7686
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7687
|
+
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7688
|
+
content: `Error: ${errorMsg}`,
|
|
7689
|
+
callId: lastCallId || existingEntry.callId || ""
|
|
7690
|
+
})
|
|
7691
|
+
});
|
|
7156
7692
|
});
|
|
7693
|
+
}
|
|
7694
|
+
} else {
|
|
7695
|
+
setError({
|
|
7696
|
+
message: errorMsg,
|
|
7697
|
+
code: "UNKNOWN_ERROR"
|
|
7157
7698
|
});
|
|
7699
|
+
if (promptKey) {
|
|
7700
|
+
setHistory((prev) => {
|
|
7701
|
+
const existingEntry = prev[promptKey] || { content: "", callId: "" };
|
|
7702
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7703
|
+
[promptKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7704
|
+
content: `Error: ${errorMsg}`,
|
|
7705
|
+
callId: lastCallId || existingEntry.callId || ""
|
|
7706
|
+
})
|
|
7707
|
+
});
|
|
7708
|
+
});
|
|
7709
|
+
}
|
|
7158
7710
|
}
|
|
7711
|
+
setIsLoading(false);
|
|
7712
|
+
releaseTurnLockIfSettled();
|
|
7159
7713
|
}
|
|
7160
|
-
|
|
7161
|
-
|
|
7714
|
+
);
|
|
7715
|
+
setLastMessages(sendMessages);
|
|
7716
|
+
if (convId && onConversationCreated) {
|
|
7717
|
+
setTimeout(() => {
|
|
7718
|
+
onConversationCreated(convId);
|
|
7719
|
+
}, 100);
|
|
7162
7720
|
}
|
|
7163
|
-
)
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
}
|
|
7721
|
+
} catch (error2) {
|
|
7722
|
+
console.error("[AIChatPanel] Failed to send prompt:", error2);
|
|
7723
|
+
setError({
|
|
7724
|
+
message: error2 instanceof Error ? error2.message : "Failed to send prompt",
|
|
7725
|
+
code: "UNKNOWN_ERROR"
|
|
7726
|
+
});
|
|
7727
|
+
setIsLoading(false);
|
|
7728
|
+
releaseTurnLockIfSettled();
|
|
7169
7729
|
}
|
|
7170
|
-
})
|
|
7171
|
-
console.error("[AIChatPanel] Failed to send prompt:", error2);
|
|
7172
|
-
setError({
|
|
7173
|
-
message: error2 instanceof Error ? error2.message : "Failed to send prompt",
|
|
7174
|
-
code: "UNKNOWN_ERROR"
|
|
7175
|
-
});
|
|
7176
|
-
setIsLoading(false);
|
|
7177
|
-
releaseTurnLockIfSettled();
|
|
7178
|
-
});
|
|
7730
|
+
}))();
|
|
7179
7731
|
}, [
|
|
7180
7732
|
clearFollowOnQuestionsNextPrompt,
|
|
7181
7733
|
promptTemplate,
|
|
@@ -7190,6 +7742,10 @@ ${traceSummary}` : traceSummary;
|
|
|
7190
7742
|
scrollToBottom,
|
|
7191
7743
|
onConversationCreated,
|
|
7192
7744
|
onBeforeSend,
|
|
7745
|
+
compactContext,
|
|
7746
|
+
compactionPreserveTurns,
|
|
7747
|
+
maxContextTokens,
|
|
7748
|
+
totalContextTokens,
|
|
7193
7749
|
hasInFlightTurnWork,
|
|
7194
7750
|
queuePromptForLater,
|
|
7195
7751
|
releaseTurnLockIfSettled,
|
|
@@ -7209,8 +7765,15 @@ ${traceSummary}` : traceSummary;
|
|
|
7209
7765
|
continueChat(question);
|
|
7210
7766
|
}, [continueChat]);
|
|
7211
7767
|
const handleStop = useCallback2(() => {
|
|
7768
|
+
if (pendingUserInputRequest) {
|
|
7769
|
+
completePendingUserInputRequest({
|
|
7770
|
+
status: "cancelled",
|
|
7771
|
+
requestId: pendingUserInputRequest.requestId,
|
|
7772
|
+
cancelledBy: "stop"
|
|
7773
|
+
});
|
|
7774
|
+
}
|
|
7212
7775
|
stop(lastController);
|
|
7213
|
-
}, [
|
|
7776
|
+
}, [completePendingUserInputRequest, lastController, pendingUserInputRequest, stop]);
|
|
7214
7777
|
const handleNewConversation = useCallback2(() => {
|
|
7215
7778
|
if (!newConversationConfirm) {
|
|
7216
7779
|
setNewConversationConfirm(true);
|
|
@@ -7221,8 +7784,16 @@ ${traceSummary}` : traceSummary;
|
|
|
7221
7784
|
if (!idle) {
|
|
7222
7785
|
stop(lastController);
|
|
7223
7786
|
}
|
|
7787
|
+
if (pendingUserInputRequest) {
|
|
7788
|
+
completePendingUserInputRequest({
|
|
7789
|
+
status: "cancelled",
|
|
7790
|
+
requestId: pendingUserInputRequest.requestId,
|
|
7791
|
+
cancelledBy: "reset"
|
|
7792
|
+
});
|
|
7793
|
+
}
|
|
7224
7794
|
setResponse("");
|
|
7225
7795
|
setHistory({});
|
|
7796
|
+
setCompactionNotice(null);
|
|
7226
7797
|
latestHistoryRef.current = {};
|
|
7227
7798
|
hasNotifiedCompletionRef.current = true;
|
|
7228
7799
|
queuedPromptsRef.current = [];
|
|
@@ -7244,6 +7815,7 @@ ${traceSummary}` : traceSummary;
|
|
|
7244
7815
|
setThinkingBlocks([]);
|
|
7245
7816
|
setCurrentThinkingIndex(0);
|
|
7246
7817
|
setCollapsedBlocks(/* @__PURE__ */ new Set());
|
|
7818
|
+
setPendingUserInputRequest(null);
|
|
7247
7819
|
hasAutoCollapsedRef.current = false;
|
|
7248
7820
|
prevBlockCountRef.current = 0;
|
|
7249
7821
|
setJustReset(true);
|
|
@@ -7257,7 +7829,16 @@ ${traceSummary}` : traceSummary;
|
|
|
7257
7829
|
setJustReset(false);
|
|
7258
7830
|
(_a2 = responseAreaRef.current) == null ? void 0 : _a2.scrollTo({ top: 0, behavior: "smooth" });
|
|
7259
7831
|
}, 100);
|
|
7260
|
-
}, [
|
|
7832
|
+
}, [
|
|
7833
|
+
completePendingUserInputRequest,
|
|
7834
|
+
followOnQuestions,
|
|
7835
|
+
idle,
|
|
7836
|
+
lastController,
|
|
7837
|
+
newConversationConfirm,
|
|
7838
|
+
pendingUserInputRequest,
|
|
7839
|
+
setResponse,
|
|
7840
|
+
stop
|
|
7841
|
+
]);
|
|
7261
7842
|
useEffect8(() => {
|
|
7262
7843
|
if (!response || !lastKey || justReset) return;
|
|
7263
7844
|
const extractedToolRequests = extractToolRequests(response);
|
|
@@ -7971,6 +8552,15 @@ ${traceSummary}` : traceSummary;
|
|
|
7971
8552
|
},
|
|
7972
8553
|
/* @__PURE__ */ React14.createElement(CloseIcon, null)
|
|
7973
8554
|
)),
|
|
8555
|
+
compactionNotice && compactionNotice.level !== "info" && /* @__PURE__ */ React14.createElement("div", { className: `ai-chat-compaction-banner ai-chat-compaction-banner--${compactionNotice.level}` }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-compaction-banner__message" }, compactionNotice.message), /* @__PURE__ */ React14.createElement(
|
|
8556
|
+
"button",
|
|
8557
|
+
{
|
|
8558
|
+
className: "ai-chat-compaction-banner__close",
|
|
8559
|
+
onClick: () => setCompactionNotice(null),
|
|
8560
|
+
"aria-label": "Dismiss context notice"
|
|
8561
|
+
},
|
|
8562
|
+
/* @__PURE__ */ React14.createElement(CloseIcon, null)
|
|
8563
|
+
)),
|
|
7974
8564
|
/* @__PURE__ */ React14.createElement(ScrollArea, { className: "ai-chat-panel__messages", ref: responseAreaRef }, initialMessage && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-message ai-chat-message--assistant" }, /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-message__content" }, markdownClass ? /* @__PURE__ */ React14.createElement("div", { className: markdownClass }, /* @__PURE__ */ React14.createElement(
|
|
7975
8565
|
ReactMarkdown2,
|
|
7976
8566
|
{
|
|
@@ -8153,6 +8743,7 @@ ${traceSummary}` : traceSummary;
|
|
|
8153
8743
|
},
|
|
8154
8744
|
question
|
|
8155
8745
|
))), /* @__PURE__ */ React14.createElement("div", { ref: bottomRef })),
|
|
8746
|
+
(compactionNotice == null ? void 0 : compactionNotice.level) === "info" && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-compaction-inline-status", role: "status", "aria-live": "polite" }, /* @__PURE__ */ React14.createElement("span", null, compactionNotice.message)),
|
|
8156
8747
|
(showSaveButton || showEmailButton || showCallToAction) && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-button-container" }, showSaveButton && /* @__PURE__ */ React14.createElement(
|
|
8157
8748
|
Button,
|
|
8158
8749
|
{
|
|
@@ -8292,6 +8883,8 @@ ${traceSummary}` : traceSummary;
|
|
|
8292
8883
|
onSubmit: continueChat,
|
|
8293
8884
|
onQueueSubmit: handleQueuePrompt,
|
|
8294
8885
|
onStop: handleStop,
|
|
8886
|
+
userInputRequest: pendingUserInputRequest,
|
|
8887
|
+
onCompleteUserInputRequest: completePendingUserInputRequest,
|
|
8295
8888
|
queuedPrompts,
|
|
8296
8889
|
onClearQueuedPrompt: handleClearQueuedPrompt,
|
|
8297
8890
|
agentOptions,
|
|
@@ -8305,7 +8898,8 @@ ${traceSummary}` : traceSummary;
|
|
|
8305
8898
|
maxContextTokens,
|
|
8306
8899
|
enableContextDetailView,
|
|
8307
8900
|
disabledSectionIds,
|
|
8308
|
-
onToggleSection: handleToggleSection
|
|
8901
|
+
onToggleSection: handleToggleSection,
|
|
8902
|
+
composerAgentModeControl
|
|
8309
8903
|
}
|
|
8310
8904
|
),
|
|
8311
8905
|
showPoweredBy && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-panel__footer" }, mcpServers && mcpServers.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: "ai-chat-tools-status" }, /* @__PURE__ */ React14.createElement(
|
|
@@ -8543,7 +9137,7 @@ var normalizeConversationListPayload = (payload) => {
|
|
|
8543
9137
|
if (!title) {
|
|
8544
9138
|
title = conv.summary || extractTitleFromConversation(conv);
|
|
8545
9139
|
}
|
|
8546
|
-
const resolvedConversationId = conv.conversationId || conv.id || conv.conversation_id || `conversation-${index}-${Date.now()}`;
|
|
9140
|
+
const resolvedConversationId = conv.sessionId || conv.session_id || conv.sessionKey || conv.session_key || conv.conversationId || conv.id || conv.conversation_id || `conversation-${index}-${Date.now()}`;
|
|
8547
9141
|
return {
|
|
8548
9142
|
conversationId: resolvedConversationId,
|
|
8549
9143
|
title,
|
|
@@ -9032,6 +9626,8 @@ var ChatPanelWrapper = ({
|
|
|
9032
9626
|
onToggleSection,
|
|
9033
9627
|
onConversationCreated,
|
|
9034
9628
|
onBeforeSend,
|
|
9629
|
+
compactContext,
|
|
9630
|
+
compactionPreserveTurns,
|
|
9035
9631
|
conversationInitialPrompt,
|
|
9036
9632
|
// New props from ChatPanel port
|
|
9037
9633
|
cssUrl,
|
|
@@ -9053,7 +9649,8 @@ var ChatPanelWrapper = ({
|
|
|
9053
9649
|
localToolExecutors,
|
|
9054
9650
|
traceContextMode,
|
|
9055
9651
|
autoApproveTools,
|
|
9056
|
-
toolStatusLabelFormatter
|
|
9652
|
+
toolStatusLabelFormatter,
|
|
9653
|
+
composerAgentModeControl
|
|
9057
9654
|
}) => {
|
|
9058
9655
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
9059
9656
|
const convAgentProfile = getAgent(activeConv.agentId);
|
|
@@ -9151,6 +9748,8 @@ var ChatPanelWrapper = ({
|
|
|
9151
9748
|
onToggleSection,
|
|
9152
9749
|
onConversationCreated: conversationCreatedCallback,
|
|
9153
9750
|
onBeforeSend: beforeSendCallback,
|
|
9751
|
+
compactContext,
|
|
9752
|
+
compactionPreserveTurns,
|
|
9154
9753
|
cssUrl,
|
|
9155
9754
|
markdownClass,
|
|
9156
9755
|
width,
|
|
@@ -9170,7 +9769,8 @@ var ChatPanelWrapper = ({
|
|
|
9170
9769
|
localToolExecutors,
|
|
9171
9770
|
traceContextMode,
|
|
9172
9771
|
autoApproveTools,
|
|
9173
|
-
toolStatusLabelFormatter
|
|
9772
|
+
toolStatusLabelFormatter,
|
|
9773
|
+
composerAgentModeControl
|
|
9174
9774
|
}
|
|
9175
9775
|
)
|
|
9176
9776
|
);
|
|
@@ -9222,6 +9822,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9222
9822
|
onAgentSwitch,
|
|
9223
9823
|
onConversationChange,
|
|
9224
9824
|
onBeforeSend,
|
|
9825
|
+
compactContext,
|
|
9826
|
+
compactionPreserveTurns,
|
|
9225
9827
|
historyChangedCallback,
|
|
9226
9828
|
responseCompleteCallback,
|
|
9227
9829
|
thumbsUpClick,
|
|
@@ -9237,6 +9839,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9237
9839
|
followOnQuestions = [],
|
|
9238
9840
|
followOnPrompt = "",
|
|
9239
9841
|
historyListLimit = 50,
|
|
9842
|
+
conversationSubtitleResolver,
|
|
9240
9843
|
showConversationHistory = true,
|
|
9241
9844
|
// New props from ChatPanel port
|
|
9242
9845
|
cssUrl,
|
|
@@ -9258,7 +9861,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9258
9861
|
localToolExecutors,
|
|
9259
9862
|
traceContextMode = "standard",
|
|
9260
9863
|
autoApproveTools,
|
|
9261
|
-
toolStatusLabelFormatter
|
|
9864
|
+
toolStatusLabelFormatter,
|
|
9865
|
+
composerAgentModeControl
|
|
9262
9866
|
}, ref) => {
|
|
9263
9867
|
var _a, _b, _c, _d;
|
|
9264
9868
|
useEffect10(() => {
|
|
@@ -9396,6 +10000,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9396
10000
|
"This Month": false,
|
|
9397
10001
|
"Older": false
|
|
9398
10002
|
});
|
|
10003
|
+
const [recentlyFocusedConversationId, setRecentlyFocusedConversationId] = useState9(null);
|
|
9399
10004
|
const [disabledContextSections, setDisabledContextSections] = useState9(/* @__PURE__ */ new Map());
|
|
9400
10005
|
const {
|
|
9401
10006
|
agents: agentProfiles,
|
|
@@ -9781,8 +10386,11 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9781
10386
|
if (loadingConversationId === targetConversationId) {
|
|
9782
10387
|
return;
|
|
9783
10388
|
}
|
|
10389
|
+
if (currentConversationIdRef.current !== targetConversationId) {
|
|
10390
|
+
setCurrentConversationId(targetConversationId);
|
|
10391
|
+
}
|
|
9784
10392
|
const existingActive = activeConversationsRef.current.get(targetConversationId);
|
|
9785
|
-
if (existingActive && existingActive.transcriptLoaded
|
|
10393
|
+
if (existingActive && existingActive.transcriptLoaded) {
|
|
9786
10394
|
return;
|
|
9787
10395
|
}
|
|
9788
10396
|
const apiConversation = apiConversations.find(
|
|
@@ -9922,6 +10530,50 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9922
10530
|
}
|
|
9923
10531
|
return groupConversationsByTime(filtered, true);
|
|
9924
10532
|
}, [apiConversations, searchQuery, conversationFirstPrompts]);
|
|
10533
|
+
useEffect10(() => {
|
|
10534
|
+
if (!currentConversationId) {
|
|
10535
|
+
return;
|
|
10536
|
+
}
|
|
10537
|
+
const matchingGroup = groupedConversations.find(
|
|
10538
|
+
(group) => group.conversations.some((conversation2) => conversation2.conversationId === currentConversationId)
|
|
10539
|
+
);
|
|
10540
|
+
if (!matchingGroup) {
|
|
10541
|
+
return;
|
|
10542
|
+
}
|
|
10543
|
+
setExpandedSections((prev) => {
|
|
10544
|
+
if (prev[matchingGroup.label]) {
|
|
10545
|
+
return prev;
|
|
10546
|
+
}
|
|
10547
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
10548
|
+
[matchingGroup.label]: true
|
|
10549
|
+
});
|
|
10550
|
+
});
|
|
10551
|
+
}, [currentConversationId, groupedConversations]);
|
|
10552
|
+
useEffect10(() => {
|
|
10553
|
+
if (!currentConversationId) {
|
|
10554
|
+
return;
|
|
10555
|
+
}
|
|
10556
|
+
setRecentlyFocusedConversationId(currentConversationId);
|
|
10557
|
+
const timer = window.setTimeout(() => {
|
|
10558
|
+
setRecentlyFocusedConversationId((prev) => prev === currentConversationId ? null : prev);
|
|
10559
|
+
}, 1200);
|
|
10560
|
+
return () => window.clearTimeout(timer);
|
|
10561
|
+
}, [currentConversationId]);
|
|
10562
|
+
const conversationRowRefs = useRef7(/* @__PURE__ */ new Map());
|
|
10563
|
+
useEffect10(() => {
|
|
10564
|
+
if (!currentConversationId) {
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10567
|
+
const row = conversationRowRefs.current.get(currentConversationId);
|
|
10568
|
+
if (!row) {
|
|
10569
|
+
return;
|
|
10570
|
+
}
|
|
10571
|
+
row.scrollIntoView({
|
|
10572
|
+
block: "nearest",
|
|
10573
|
+
inline: "nearest",
|
|
10574
|
+
behavior: "smooth"
|
|
10575
|
+
});
|
|
10576
|
+
}, [currentConversationId, expandedSections, groupedConversations]);
|
|
9925
10577
|
const effectiveCustomer = useMemo4(() => {
|
|
9926
10578
|
return __spreadProps(__spreadValues({}, customer), {
|
|
9927
10579
|
customer_id: customerId
|
|
@@ -10496,26 +11148,36 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
10496
11148
|
onClick: handleNewConversation
|
|
10497
11149
|
},
|
|
10498
11150
|
/* @__PURE__ */ React15.createElement(PlusIcon, null)
|
|
10499
|
-
))), /* @__PURE__ */ React15.createElement(Tooltip, { content: "Collapse History", side: "bottom" }, /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", size: "icon", onClick: toggleHistoryCollapse }, /* @__PURE__ */ React15.createElement(SidebarIcon, null))), collapsible && /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", size: "icon", onClick: toggleCollapse }, position === "right" ? /* @__PURE__ */ React15.createElement(ChevronRightIcon, null) : /* @__PURE__ */ React15.createElement(ChevronLeftIcon, null))), /* @__PURE__ */ React15.createElement(ScrollArea, { className: "ai-agent-panel__conversations" }, activeConversationsList.length > 0 && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__group ai-agent-panel__group--active" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__group-label" }, /* @__PURE__ */ React15.createElement("span", null, "Active (", activeConversationsList.length, ")")), activeConversationsList.map((activeConv) =>
|
|
10500
|
-
"
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
className: `ai-agent-panel__conversation ai-agent-panel__conversation--active-item ${currentConversationId === activeConv.conversationId ? "ai-agent-panel__conversation--current" : ""}`,
|
|
10504
|
-
onClick: () => {
|
|
10505
|
-
commitConversationSelection(activeConv.conversationId, true);
|
|
10506
|
-
}
|
|
10507
|
-
},
|
|
10508
|
-
/* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-content" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-title" }, activeConv.isLoading && /* @__PURE__ */ React15.createElement(LoadingDotIcon, null), /* @__PURE__ */ React15.createElement("span", null, activeConv.title))),
|
|
10509
|
-
/* @__PURE__ */ React15.createElement(
|
|
10510
|
-
"button",
|
|
11151
|
+
))), /* @__PURE__ */ React15.createElement(Tooltip, { content: "Collapse History", side: "bottom" }, /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", size: "icon", onClick: toggleHistoryCollapse }, /* @__PURE__ */ React15.createElement(SidebarIcon, null))), collapsible && /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", size: "icon", onClick: toggleCollapse }, position === "right" ? /* @__PURE__ */ React15.createElement(ChevronRightIcon, null) : /* @__PURE__ */ React15.createElement(ChevronLeftIcon, null))), /* @__PURE__ */ React15.createElement(ScrollArea, { className: "ai-agent-panel__conversations" }, activeConversationsList.length > 0 && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__group ai-agent-panel__group--active" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__group-label" }, /* @__PURE__ */ React15.createElement("span", null, "Active (", activeConversationsList.length, ")")), activeConversationsList.map((activeConv) => {
|
|
11152
|
+
const subtitle = (conversationSubtitleResolver == null ? void 0 : conversationSubtitleResolver(activeConv.conversationId, activeConv)) || "";
|
|
11153
|
+
return /* @__PURE__ */ React15.createElement(
|
|
11154
|
+
"div",
|
|
10511
11155
|
{
|
|
10512
|
-
|
|
10513
|
-
|
|
10514
|
-
|
|
11156
|
+
key: activeConv.stableKey,
|
|
11157
|
+
className: `ai-agent-panel__conversation ai-agent-panel__conversation--active-item ${currentConversationId === activeConv.conversationId ? "ai-agent-panel__conversation--current" : ""} ${recentlyFocusedConversationId === activeConv.conversationId ? "ai-agent-panel__conversation--just-focused" : ""}`,
|
|
11158
|
+
ref: (node) => {
|
|
11159
|
+
if (node) {
|
|
11160
|
+
conversationRowRefs.current.set(activeConv.conversationId, node);
|
|
11161
|
+
} else {
|
|
11162
|
+
conversationRowRefs.current.delete(activeConv.conversationId);
|
|
11163
|
+
}
|
|
11164
|
+
},
|
|
11165
|
+
onClick: () => {
|
|
11166
|
+
commitConversationSelection(activeConv.conversationId, true);
|
|
11167
|
+
}
|
|
10515
11168
|
},
|
|
10516
|
-
/* @__PURE__ */ React15.createElement(
|
|
10517
|
-
|
|
10518
|
-
|
|
11169
|
+
/* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-content" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-title" }, activeConv.isLoading && /* @__PURE__ */ React15.createElement(LoadingDotIcon, null), /* @__PURE__ */ React15.createElement("span", null, activeConv.title)), subtitle ? /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-subtitle" }, subtitle) : null),
|
|
11170
|
+
/* @__PURE__ */ React15.createElement(
|
|
11171
|
+
"button",
|
|
11172
|
+
{
|
|
11173
|
+
className: "ai-agent-panel__conversation-close",
|
|
11174
|
+
onClick: (e) => handleCloseConversation(activeConv.conversationId, e),
|
|
11175
|
+
title: "Close conversation"
|
|
11176
|
+
},
|
|
11177
|
+
/* @__PURE__ */ React15.createElement(CloseIcon2, null)
|
|
11178
|
+
)
|
|
11179
|
+
);
|
|
11180
|
+
})), conversationsLoading ? /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__loading" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ React15.createElement("span", null, "Loading conversations...")) : conversationsError ? /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__empty" }, /* @__PURE__ */ React15.createElement("p", null, "Error: ", conversationsError), /* @__PURE__ */ React15.createElement(Button, { variant: "secondary", size: "sm", onClick: handleRefreshConversations }, "Retry")) : groupedConversations.length === 0 && activeConversationsList.length === 0 ? /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__empty" }, /* @__PURE__ */ React15.createElement(MessageIcon, null), /* @__PURE__ */ React15.createElement("p", null, "No conversations yet"), /* @__PURE__ */ React15.createElement("p", { className: "ai-agent-panel__empty-hint" }, "Start chatting to create your first conversation")) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, activeConversationsList.length > 0 && groupedConversations.some((g) => g.count > 0) && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__group-divider" }), groupedConversations.map((group) => /* @__PURE__ */ React15.createElement("div", { key: group.label, className: "ai-agent-panel__group" }, /* @__PURE__ */ React15.createElement(
|
|
10519
11181
|
"div",
|
|
10520
11182
|
{
|
|
10521
11183
|
className: "ai-agent-panel__group-label ai-agent-panel__group-label--clickable",
|
|
@@ -10525,14 +11187,22 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
10525
11187
|
/* @__PURE__ */ React15.createElement("span", { className: "ai-agent-panel__group-chevron" }, expandedSections[group.label] ? "\u25BC" : "\u25B6")
|
|
10526
11188
|
), expandedSections[group.label] && group.conversations.length > 0 && group.conversations.map((conv, convIndex) => {
|
|
10527
11189
|
const isActive = activeConversations.has(conv.conversationId);
|
|
11190
|
+
const subtitle = (conversationSubtitleResolver == null ? void 0 : conversationSubtitleResolver(conv.conversationId, conv)) || "";
|
|
10528
11191
|
return /* @__PURE__ */ React15.createElement(
|
|
10529
11192
|
"div",
|
|
10530
11193
|
{
|
|
10531
11194
|
key: `${group.label}-${conv.conversationId}-${convIndex}`,
|
|
10532
|
-
className: `ai-agent-panel__conversation ${currentConversationId === conv.conversationId ? "ai-agent-panel__conversation--current" : ""} ${isActive ? "ai-agent-panel__conversation--in-active" : ""}`,
|
|
11195
|
+
className: `ai-agent-panel__conversation ${currentConversationId === conv.conversationId ? "ai-agent-panel__conversation--current" : ""} ${recentlyFocusedConversationId === conv.conversationId ? "ai-agent-panel__conversation--just-focused" : ""} ${isActive ? "ai-agent-panel__conversation--in-active" : ""}`,
|
|
11196
|
+
ref: (node) => {
|
|
11197
|
+
if (node) {
|
|
11198
|
+
conversationRowRefs.current.set(conv.conversationId, node);
|
|
11199
|
+
} else {
|
|
11200
|
+
conversationRowRefs.current.delete(conv.conversationId);
|
|
11201
|
+
}
|
|
11202
|
+
},
|
|
10533
11203
|
onClick: () => handleConversationSelect(conv)
|
|
10534
11204
|
},
|
|
10535
|
-
/* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-content" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-title" }, isActive && /* @__PURE__ */ React15.createElement("span", { className: "ai-agent-panel__active-badge" }, "\u25CF"), conversationFirstPrompts[conv.conversationId] || conv.title))
|
|
11205
|
+
/* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-content" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-title" }, isActive && /* @__PURE__ */ React15.createElement("span", { className: "ai-agent-panel__active-badge" }, "\u25CF"), conversationFirstPrompts[conv.conversationId] || conv.title), subtitle ? /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-subtitle" }, subtitle) : null)
|
|
10536
11206
|
);
|
|
10537
11207
|
}))))))),
|
|
10538
11208
|
/* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__chat" }, !showConversationHistory && collapsible && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__chat-header" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__chat-header-spacer" }), /* @__PURE__ */ React15.createElement(Tooltip, { content: "Collapse Panel", side: position === "right" ? "left" : "right" }, /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", size: "icon", onClick: toggleCollapse }, position === "right" ? /* @__PURE__ */ React15.createElement(ChevronRightIcon, null) : /* @__PURE__ */ React15.createElement(ChevronLeftIcon, null)))), showContextNotification && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__context-notification" }, /* @__PURE__ */ React15.createElement(SparkleIcon, null), /* @__PURE__ */ React15.createElement("span", null, "Agent now has new context")), activeConversationsList.map((activeConv) => /* @__PURE__ */ React15.createElement(
|
|
@@ -10570,6 +11240,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
10570
11240
|
onToggleSection: handleContextSectionToggle,
|
|
10571
11241
|
onConversationCreated: handleConversationCreated,
|
|
10572
11242
|
onBeforeSend,
|
|
11243
|
+
compactContext,
|
|
11244
|
+
compactionPreserveTurns,
|
|
10573
11245
|
conversationInitialPrompt: activeConv.conversationInitialPrompt,
|
|
10574
11246
|
cssUrl,
|
|
10575
11247
|
markdownClass,
|
|
@@ -10590,7 +11262,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
10590
11262
|
localToolExecutors,
|
|
10591
11263
|
traceContextMode,
|
|
10592
11264
|
autoApproveTools,
|
|
10593
|
-
toolStatusLabelFormatter
|
|
11265
|
+
toolStatusLabelFormatter,
|
|
11266
|
+
composerAgentModeControl
|
|
10594
11267
|
}
|
|
10595
11268
|
)), loadingConversationId && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__conversation-loading-overlay" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ React15.createElement("p", null, "Loading conversation...")), currentAgentMetadata && activeConversationsList.length === 0 && !loadingConversationId && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__empty-chat" }, /* @__PURE__ */ React15.createElement(MessageIcon, null), /* @__PURE__ */ React15.createElement("p", null, "Select a conversation or start a new one"), /* @__PURE__ */ React15.createElement(Button, { variant: "default", size: "sm", onClick: handleNewConversation }, "New Conversation")), agentsLoading && !currentAgentMetadata && /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__loading" }, /* @__PURE__ */ React15.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ React15.createElement("p", null, "Loading agent..."))),
|
|
10596
11269
|
/* @__PURE__ */ React15.createElement(
|