@burtson-labs/bandit-engine 2.0.55 → 2.0.57
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 +76 -76
- package/dist/{chat-IDE6Z4Q4.mjs → chat-MXC6O7M5.mjs} +3 -3
- package/dist/chat-provider.js +20 -67
- package/dist/chat-provider.js.map +1 -1
- package/dist/chat-provider.mjs +2 -2
- package/dist/{chunk-TLY6A6XL.mjs → chunk-N7GCS2BH.mjs} +156 -113
- package/dist/chunk-N7GCS2BH.mjs.map +1 -0
- package/dist/{chunk-AVV7HDGR.mjs → chunk-POTQI33D.mjs} +2 -2
- package/dist/{chunk-EHNWQ4T3.mjs → chunk-QPBG6JQE.mjs} +21 -68
- package/dist/chunk-QPBG6JQE.mjs.map +1 -0
- package/dist/{chunk-NP2OHTTX.mjs → chunk-VU5N57QZ.mjs} +3 -3
- package/dist/index.js +176 -180
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/management/management.js +176 -180
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +2 -2
- package/package.json +2 -2
- package/dist/chunk-EHNWQ4T3.mjs.map +0 -1
- package/dist/chunk-TLY6A6XL.mjs.map +0 -1
- /package/dist/{chat-IDE6Z4Q4.mjs.map → chat-MXC6O7M5.mjs.map} +0 -0
- /package/dist/{chunk-AVV7HDGR.mjs.map → chunk-POTQI33D.mjs.map} +0 -0
- /package/dist/{chunk-NP2OHTTX.mjs.map → chunk-VU5N57QZ.mjs.map} +0 -0
package/dist/chat-provider.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ChatProvider,
|
|
3
3
|
chat_provider_default
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-POTQI33D.mjs";
|
|
5
5
|
import "./chunk-ONQMRE2G.mjs";
|
|
6
6
|
import "./chunk-UFSEYVRS.mjs";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-QPBG6JQE.mjs";
|
|
8
8
|
import "./chunk-557E5VZ2.mjs";
|
|
9
9
|
import "./chunk-7ZDS33S2.mjs";
|
|
10
10
|
import "./chunk-H3BYFEIE.mjs";
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-KM7FUWCM.mjs";
|
|
7
7
|
import {
|
|
8
8
|
useMCPToolsStore
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QPBG6JQE.mjs";
|
|
10
10
|
import {
|
|
11
11
|
AddIcon,
|
|
12
12
|
ArrowDownwardIcon,
|
|
@@ -488,7 +488,7 @@ var STTClient = class {
|
|
|
488
488
|
normalizedBlob = new Blob([blob], { type: "audio/webm" });
|
|
489
489
|
}
|
|
490
490
|
const body = new FormData();
|
|
491
|
-
const filename = normalizedBlob.type.includes("ogg") ? "audio.ogg" : normalizedBlob.type.includes("wav") ? "audio.wav" : normalizedBlob.type.includes("mp3") ? "audio.mp3" : "audio.webm";
|
|
491
|
+
const filename = normalizedBlob.type.includes("ogg") ? "audio.ogg" : normalizedBlob.type.includes("wav") ? "audio.wav" : normalizedBlob.type.includes("mp4") || normalizedBlob.type.includes("m4a") || normalizedBlob.type.includes("aac") ? "audio.mp4" : normalizedBlob.type.includes("mp3") ? "audio.mp3" : "audio.webm";
|
|
492
492
|
body.append("audio", normalizedBlob, filename);
|
|
493
493
|
body.append("file", normalizedBlob, filename);
|
|
494
494
|
body.append("audioFile", normalizedBlob, filename);
|
|
@@ -2734,6 +2734,7 @@ USE THE ABOVE CONTENT to answer the user's question. Reference specific informat
|
|
|
2734
2734
|
- Only use tools for live data (news, weather, sports scores) when specifically requested
|
|
2735
2735
|
- Trust and utilize the provided context without hesitation`;
|
|
2736
2736
|
enhancedSystemPrompt += ragGuidance;
|
|
2737
|
+
const systemPromptForSummary = enhancedSystemPrompt;
|
|
2737
2738
|
const mcpToolsAvailable = isMCPAvailable();
|
|
2738
2739
|
if (mcpToolsAvailable) {
|
|
2739
2740
|
const enabledTools = getEnabledMCPToolsForAI();
|
|
@@ -2749,10 +2750,10 @@ USE THE ABOVE CONTENT to answer the user's question. Reference specific informat
|
|
|
2749
2750
|
TOOL USAGE PROTOCOL (conservative approach)
|
|
2750
2751
|
- PRIORITIZE your built-in knowledge and the provided context ABOVE to answer questions first.
|
|
2751
2752
|
- Use your training data and general knowledge confidently for common topics, concepts, and questions.
|
|
2752
|
-
- Only call tools for SPECIFIC, CURRENT information that requires real-time data:
|
|
2753
|
-
*
|
|
2754
|
-
*
|
|
2755
|
-
*
|
|
2753
|
+
- Only call tools for SPECIFIC, CURRENT information that requires real-time data or a source you don't already have:
|
|
2754
|
+
* web_search() - when asked about recent/current events, breaking news, live information (weather, prices, sports scores), or when you need to look up documentation, libraries, APIs, error messages, or verify a specific fact
|
|
2755
|
+
* web_fetch() - ONLY when you already have a specific URL whose contents you need to read
|
|
2756
|
+
* image_generation() - ONLY when explicitly asked to create or generate an image
|
|
2756
2757
|
- For general questions about concepts, definitions, explanations, or how-to topics, use your built-in knowledge WITHOUT calling tools.
|
|
2757
2758
|
- Examples of what NOT to use tools for: "who are you?", "what is React?", "explain machine learning", "how does X work?", general programming questions.
|
|
2758
2759
|
- When a tool is truly needed, call exactly ONE tool that best matches the request.
|
|
@@ -2764,11 +2765,11 @@ functionName({"param": "value"})
|
|
|
2764
2765
|
Examples of appropriate tool usage:
|
|
2765
2766
|
|
|
2766
2767
|
\`\`\`tool_code
|
|
2767
|
-
|
|
2768
|
+
web_search({"query": "latest AI developments 2026", "count": 5})
|
|
2768
2769
|
\`\`\`
|
|
2769
2770
|
|
|
2770
2771
|
\`\`\`tool_code
|
|
2771
|
-
|
|
2772
|
+
web_fetch({"url": "https://example.com/changelog"})
|
|
2772
2773
|
\`\`\`
|
|
2773
2774
|
`;
|
|
2774
2775
|
enhancedSystemPrompt += `
|
|
@@ -2811,6 +2812,7 @@ ${protocol}`;
|
|
|
2811
2812
|
if (openIdx !== -1) result = result.slice(0, openIdx);
|
|
2812
2813
|
return result.trimStart();
|
|
2813
2814
|
};
|
|
2815
|
+
const stripToolBlocks = (text) => text.replace(/```(?:tool_code|TOOL_CODE)\s*\n[\s\S]*?\n```/gi, "").trim();
|
|
2814
2816
|
const flushNow = () => {
|
|
2815
2817
|
clearFlushTimer();
|
|
2816
2818
|
if (!sawToolBlock) {
|
|
@@ -2884,6 +2886,8 @@ ${protocol}`;
|
|
|
2884
2886
|
}
|
|
2885
2887
|
const toolCallMatches = fullMessage.match(/```(?:tool_code|TOOL_CODE)\s*\n([^`]+)\n```/gi);
|
|
2886
2888
|
let enhancedMessage = fullMessage;
|
|
2889
|
+
const summarizableResults = [];
|
|
2890
|
+
const inlineImageBlocks = [];
|
|
2887
2891
|
if (toolCallMatches && toolCallMatches.length > 0 && mcpToolsAvailable) {
|
|
2888
2892
|
debugLogger.info("Detected tool calls in AI response", {
|
|
2889
2893
|
toolCallCount: toolCallMatches.length,
|
|
@@ -2924,47 +2928,43 @@ ${protocol}`;
|
|
|
2924
2928
|
});
|
|
2925
2929
|
let resultText = "";
|
|
2926
2930
|
if (result.success) {
|
|
2927
|
-
if (functionName === "
|
|
2928
|
-
const
|
|
2929
|
-
const
|
|
2930
|
-
const
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
const awayTokens = tokens(game.awayTeam);
|
|
2951
|
-
const hits = [...homeTokens, ...awayTokens].reduce(
|
|
2952
|
-
(acc, token) => acc + (q.includes(token) ? 1 : 0),
|
|
2953
|
-
0
|
|
2931
|
+
if (functionName === "web_search" || functionName === "web-search") {
|
|
2932
|
+
const search = result.data ?? {};
|
|
2933
|
+
const items = Array.isArray(search.results) ? search.results : [];
|
|
2934
|
+
const blocks = [];
|
|
2935
|
+
if (typeof search.answer === "string" && search.answer.trim().length > 0) {
|
|
2936
|
+
blocks.push(search.answer.trim());
|
|
2937
|
+
}
|
|
2938
|
+
if (items.length > 0) {
|
|
2939
|
+
blocks.push(
|
|
2940
|
+
items.slice(0, 6).map((item, index) => {
|
|
2941
|
+
const title = item.title?.trim() || "Untitled";
|
|
2942
|
+
const url = item.url?.trim();
|
|
2943
|
+
const snippet = item.content?.trim();
|
|
2944
|
+
let line = `${index + 1}. **${title}**`;
|
|
2945
|
+
if (url) line += `
|
|
2946
|
+
${url}`;
|
|
2947
|
+
if (snippet) {
|
|
2948
|
+
const truncated = snippet.length > 300 ? `${snippet.slice(0, 300)}\u2026` : snippet;
|
|
2949
|
+
line += `
|
|
2950
|
+
${truncated}`;
|
|
2951
|
+
}
|
|
2952
|
+
return line;
|
|
2953
|
+
}).join("\n\n")
|
|
2954
2954
|
);
|
|
2955
|
-
if (hits > bestScore) {
|
|
2956
|
-
bestScore = hits;
|
|
2957
|
-
best = game;
|
|
2958
|
-
}
|
|
2959
2955
|
}
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
resultText =
|
|
2965
|
-
- ${topGames.map(scoreLine).join("\n- ")}`;
|
|
2956
|
+
resultText = blocks.length ? blocks.join("\n\n") : `No results found${search.query ? ` for "${search.query}"` : ""}.`;
|
|
2957
|
+
} else if (functionName === "web_fetch" || functionName === "web-fetch") {
|
|
2958
|
+
const fetched = result.data ?? {};
|
|
2959
|
+
if (fetched.blocked || fetched.error && !fetched.content) {
|
|
2960
|
+
resultText = fetched.error || "Unable to fetch that URL.";
|
|
2966
2961
|
} else {
|
|
2967
|
-
|
|
2962
|
+
const body = (fetched.content ?? "").trim();
|
|
2963
|
+
const preview = body.length > 2e3 ? `${body.slice(0, 2e3)}\u2026` : body;
|
|
2964
|
+
const source = fetched.url ? `**Source:** ${fetched.url}
|
|
2965
|
+
|
|
2966
|
+
` : "";
|
|
2967
|
+
resultText = preview ? `${source}${preview}` : `${source}No readable content found.`;
|
|
2968
2968
|
}
|
|
2969
2969
|
} else if (functionName === "image_generation" || functionName === "image-generation") {
|
|
2970
2970
|
const imageData = result.data ?? {};
|
|
@@ -2975,63 +2975,6 @@ ${protocol}`;
|
|
|
2975
2975
|
|
|
2976
2976
|
${revisedPrompt ? `Prompt refinement: \u201C${revisedPrompt}\u201D
|
|
2977
2977
|
` : ""}Note: the image link may expire in ~2 hours.` : "Image generated successfully.";
|
|
2978
|
-
} else if (functionName === "news" && Array.isArray(result.data)) {
|
|
2979
|
-
const items = result.data.slice(0, 3);
|
|
2980
|
-
resultText = items.length ? `## Top News Results
|
|
2981
|
-
|
|
2982
|
-
${items.map((item, index) => {
|
|
2983
|
-
const title = item.title ?? "Untitled";
|
|
2984
|
-
const source = item.source ?? "Unknown";
|
|
2985
|
-
const url = item.url ?? item.link;
|
|
2986
|
-
const description = item.description ?? item.summary;
|
|
2987
|
-
const publishedAt = item.publishedAt ?? item.published;
|
|
2988
|
-
let newsItem = `### ${index + 1}. ${title}
|
|
2989
|
-
`;
|
|
2990
|
-
if (typeof description === "string" && description.length > 0) {
|
|
2991
|
-
const truncated = description.length > 150 ? `${description.slice(0, 150)}...` : description;
|
|
2992
|
-
newsItem += `${truncated}
|
|
2993
|
-
|
|
2994
|
-
`;
|
|
2995
|
-
}
|
|
2996
|
-
newsItem += `**Source:** ${source}
|
|
2997
|
-
`;
|
|
2998
|
-
if (publishedAt) {
|
|
2999
|
-
const date = new Date(publishedAt);
|
|
3000
|
-
if (!Number.isNaN(date.getTime())) {
|
|
3001
|
-
newsItem += `**Published:** ${date.toLocaleDateString()} at ${date.toLocaleTimeString(
|
|
3002
|
-
[],
|
|
3003
|
-
{ hour: "2-digit", minute: "2-digit" }
|
|
3004
|
-
)}
|
|
3005
|
-
`;
|
|
3006
|
-
}
|
|
3007
|
-
}
|
|
3008
|
-
if (typeof url === "string" && url.length > 0) {
|
|
3009
|
-
newsItem += `
|
|
3010
|
-
**[\u{1F4F0} Read Full Article](${url})**
|
|
3011
|
-
`;
|
|
3012
|
-
}
|
|
3013
|
-
return newsItem;
|
|
3014
|
-
}).join("\n---\n\n")}` : "No news results found.";
|
|
3015
|
-
} else if (functionName === "docs" && Array.isArray(result.data)) {
|
|
3016
|
-
const items = result.data.slice(0, 3);
|
|
3017
|
-
resultText = items.length ? `Relevant docs:
|
|
3018
|
-
- ${items.map((item) => {
|
|
3019
|
-
const title = item.title ?? "Untitled doc";
|
|
3020
|
-
const url = item.url ?? item.link;
|
|
3021
|
-
return url ? `${title} \u2014 ${url}` : title;
|
|
3022
|
-
}).join("\n- ")}` : "No documentation results found.";
|
|
3023
|
-
} else if (functionName === "weather") {
|
|
3024
|
-
const weatherData = result.data ?? {};
|
|
3025
|
-
const informative = [weatherData.message, weatherData.details, weatherData.error].map((value) => typeof value === "string" ? value.trim() : void 0).filter((value) => Boolean(value) && value.toLowerCase() !== "n/a");
|
|
3026
|
-
if (informative.length > 0) {
|
|
3027
|
-
const locationLabel = typeof weatherData.location === "string" && weatherData.location.length > 0 ? ` for ${weatherData.location}` : "";
|
|
3028
|
-
resultText = `Weather service notice${locationLabel}: ${informative.join(" \u2014 ")}`;
|
|
3029
|
-
} else {
|
|
3030
|
-
const parts = [weatherData.location, weatherData.description, weatherData.temperature].map(
|
|
3031
|
-
(value) => typeof value === "number" || typeof value === "string" ? String(value).trim() : void 0
|
|
3032
|
-
).filter((value) => Boolean(value));
|
|
3033
|
-
resultText = parts.length ? parts.join(" \u2014 ") : "No weather data found.";
|
|
3034
|
-
}
|
|
3035
2978
|
} else if (typeof result.data === "string") {
|
|
3036
2979
|
resultText = result.data;
|
|
3037
2980
|
} else if (result.data) {
|
|
@@ -3042,16 +2985,16 @@ ${items.map((item, index) => {
|
|
|
3042
2985
|
} else {
|
|
3043
2986
|
const data = result.data ?? {};
|
|
3044
2987
|
const informative = [data.message, data.details, data.error, result.error].map((value) => typeof value === "string" ? value.trim() : void 0).filter((value) => Boolean(value) && value.toLowerCase() !== "n/a");
|
|
3045
|
-
|
|
3046
|
-
const locationLabel = typeof data.location === "string" && data.location.length > 0 ? ` for ${data.location}` : "";
|
|
3047
|
-
resultText = `Weather service issue${locationLabel}: ${informative.join(" \u2014 ")}`;
|
|
3048
|
-
} else if (informative.length) {
|
|
3049
|
-
resultText = informative.join(" \u2014 ");
|
|
3050
|
-
} else {
|
|
3051
|
-
resultText = `I couldn't complete that request: ${result.error || "Unknown error"}.`;
|
|
3052
|
-
}
|
|
2988
|
+
resultText = informative.length ? informative.join(" \u2014 ") : `I couldn't complete that request: ${result.error || "Unknown error"}.`;
|
|
3053
2989
|
}
|
|
3054
2990
|
enhancedMessage = enhancedMessage.replace(placeholderToken, resultText);
|
|
2991
|
+
if (result.success) {
|
|
2992
|
+
if (functionName === "image_generation" || functionName === "image-generation") {
|
|
2993
|
+
inlineImageBlocks.push(resultText);
|
|
2994
|
+
} else if (functionName !== "check_gateway_health") {
|
|
2995
|
+
summarizableResults.push({ name: functionName, output: resultText });
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
3055
2998
|
debugLogger.info("Tool execution completed", {
|
|
3056
2999
|
functionName,
|
|
3057
3000
|
success: result.success,
|
|
@@ -3074,6 +3017,65 @@ ${items.map((item, index) => {
|
|
|
3074
3017
|
}
|
|
3075
3018
|
}
|
|
3076
3019
|
}
|
|
3020
|
+
if (summarizableResults.length > 0) {
|
|
3021
|
+
try {
|
|
3022
|
+
const toolResultsText = summarizableResults.map((r) => `## ${r.name}
|
|
3023
|
+
${r.output}`).join("\n\n");
|
|
3024
|
+
const summaryMessages = [
|
|
3025
|
+
{ role: "system", content: systemPromptForSummary },
|
|
3026
|
+
...contextMessages,
|
|
3027
|
+
{ role: "user", content: question },
|
|
3028
|
+
{ role: "assistant", content: stripToolBlocks(fullMessage) || "Let me look that up." },
|
|
3029
|
+
{
|
|
3030
|
+
role: "user",
|
|
3031
|
+
content: `I ran the tool(s) you requested. Here are the raw results:
|
|
3032
|
+
|
|
3033
|
+
${toolResultsText}
|
|
3034
|
+
|
|
3035
|
+
Using these results together with your own knowledge, answer my original question concisely and in a natural, well-formatted way. Cite source URLs inline when you rely on them. Do NOT output tool_code or call any tools again.`
|
|
3036
|
+
}
|
|
3037
|
+
];
|
|
3038
|
+
const summaryRequest = {
|
|
3039
|
+
model: modelName,
|
|
3040
|
+
messages: summaryMessages,
|
|
3041
|
+
stream: true,
|
|
3042
|
+
options: { num_predict: tokenLimit + 250 }
|
|
3043
|
+
};
|
|
3044
|
+
clearFlushTimer();
|
|
3045
|
+
setStreamBuffer("");
|
|
3046
|
+
const summaryText = await new Promise((resolve) => {
|
|
3047
|
+
let acc = "";
|
|
3048
|
+
const summarySub = provider.chat(summaryRequest).subscribe({
|
|
3049
|
+
next: (data) => {
|
|
3050
|
+
if (data?.message?.content) {
|
|
3051
|
+
acc += data.message.content;
|
|
3052
|
+
const visible = stripThinking(acc);
|
|
3053
|
+
latestDisplayMessage = visible;
|
|
3054
|
+
lastPartialRef.current.text = visible;
|
|
3055
|
+
setStreamBuffer(visible);
|
|
3056
|
+
}
|
|
3057
|
+
},
|
|
3058
|
+
error: (summaryErr) => {
|
|
3059
|
+
debugLogger.error("Summarization pass failed", {
|
|
3060
|
+
error: summaryErr instanceof Error ? summaryErr.message : String(summaryErr)
|
|
3061
|
+
});
|
|
3062
|
+
resolve("");
|
|
3063
|
+
},
|
|
3064
|
+
complete: () => resolve(stripThinking(acc).trim())
|
|
3065
|
+
});
|
|
3066
|
+
currentSubRef.current = summarySub;
|
|
3067
|
+
});
|
|
3068
|
+
if (summaryText.trim()) {
|
|
3069
|
+
enhancedMessage = summaryText + (inlineImageBlocks.length ? `
|
|
3070
|
+
|
|
3071
|
+
${inlineImageBlocks.join("\n\n")}` : "");
|
|
3072
|
+
}
|
|
3073
|
+
} catch (summaryError) {
|
|
3074
|
+
debugLogger.error("Summarization pass threw", {
|
|
3075
|
+
error: summaryError instanceof Error ? summaryError.message : String(summaryError)
|
|
3076
|
+
});
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3077
3079
|
}
|
|
3078
3080
|
overrideComponentStatus("Idle");
|
|
3079
3081
|
setIsSubmitting(false);
|
|
@@ -7789,6 +7791,19 @@ var computeRms = (data) => {
|
|
|
7789
7791
|
}
|
|
7790
7792
|
return Math.sqrt(sumSquares / data.length);
|
|
7791
7793
|
};
|
|
7794
|
+
var pickSupportedMimeType = () => {
|
|
7795
|
+
if (typeof MediaRecorder === "undefined" || typeof MediaRecorder.isTypeSupported !== "function") {
|
|
7796
|
+
return void 0;
|
|
7797
|
+
}
|
|
7798
|
+
const candidates = [
|
|
7799
|
+
"audio/webm;codecs=opus",
|
|
7800
|
+
"audio/webm",
|
|
7801
|
+
"audio/mp4;codecs=mp4a.40.2",
|
|
7802
|
+
"audio/mp4",
|
|
7803
|
+
"audio/aac"
|
|
7804
|
+
];
|
|
7805
|
+
return candidates.find((type) => MediaRecorder.isTypeSupported(type));
|
|
7806
|
+
};
|
|
7792
7807
|
var useVoiceMode = (config) => {
|
|
7793
7808
|
const enabled = useVoiceModeStore((state) => state.enabled);
|
|
7794
7809
|
const setStatus = useVoiceModeStore((state) => state.setStatus);
|
|
@@ -7812,10 +7827,15 @@ var useVoiceMode = (config) => {
|
|
|
7812
7827
|
let silenceStartAt = 0;
|
|
7813
7828
|
const isRecordingRef = { current: false };
|
|
7814
7829
|
const isProcessingRef = { current: false };
|
|
7830
|
+
let removeResumeListeners = null;
|
|
7815
7831
|
const amplitudeThreshold = configRef.current.amplitudeThreshold ?? 0.025;
|
|
7816
7832
|
const minSpeechMs = configRef.current.minSpeechMs ?? 180;
|
|
7817
7833
|
const minSilenceMs = configRef.current.minSilenceMs ?? 720;
|
|
7818
7834
|
const clearAudioSession = async () => {
|
|
7835
|
+
if (removeResumeListeners) {
|
|
7836
|
+
removeResumeListeners();
|
|
7837
|
+
removeResumeListeners = null;
|
|
7838
|
+
}
|
|
7819
7839
|
if (rafId) {
|
|
7820
7840
|
cancelAnimationFrame(rafId);
|
|
7821
7841
|
rafId = null;
|
|
@@ -7907,7 +7927,8 @@ var useVoiceMode = (config) => {
|
|
|
7907
7927
|
const startRecording = (stream) => {
|
|
7908
7928
|
chunks = [];
|
|
7909
7929
|
try {
|
|
7910
|
-
|
|
7930
|
+
const mimeType = pickSupportedMimeType();
|
|
7931
|
+
recorder = mimeType ? new MediaRecorder(stream, { mimeType }) : new MediaRecorder(stream);
|
|
7911
7932
|
recorder.addEventListener("dataavailable", (event) => {
|
|
7912
7933
|
if (event.data && event.data.size > 0) {
|
|
7913
7934
|
chunks.push(event.data);
|
|
@@ -8001,6 +8022,28 @@ var useVoiceMode = (config) => {
|
|
|
8001
8022
|
dataArray
|
|
8002
8023
|
};
|
|
8003
8024
|
resetTransientState();
|
|
8025
|
+
if (audioContext.state === "suspended") {
|
|
8026
|
+
try {
|
|
8027
|
+
await audioContext.resume();
|
|
8028
|
+
} catch (resumeError) {
|
|
8029
|
+
debugLogger.warn("Voice mode audio context resume failed", { error: resumeError });
|
|
8030
|
+
}
|
|
8031
|
+
}
|
|
8032
|
+
if (!cancelled && audioContext.state === "suspended") {
|
|
8033
|
+
const resumeOnGesture = () => {
|
|
8034
|
+
audioContext.resume().catch(() => void 0);
|
|
8035
|
+
};
|
|
8036
|
+
const gestureEvents = ["touchend", "pointerdown", "click"];
|
|
8037
|
+
gestureEvents.forEach(
|
|
8038
|
+
(evt) => window.addEventListener(evt, resumeOnGesture, { once: true, passive: true })
|
|
8039
|
+
);
|
|
8040
|
+
removeResumeListeners = () => {
|
|
8041
|
+
gestureEvents.forEach((evt) => window.removeEventListener(evt, resumeOnGesture));
|
|
8042
|
+
};
|
|
8043
|
+
}
|
|
8044
|
+
if (cancelled) {
|
|
8045
|
+
return;
|
|
8046
|
+
}
|
|
8004
8047
|
monitorAudio();
|
|
8005
8048
|
} catch (error) {
|
|
8006
8049
|
debugLogger.error("Voice mode failed to initialize microphone", {
|
|
@@ -9177,4 +9220,4 @@ var chat_default = Chat;
|
|
|
9177
9220
|
export {
|
|
9178
9221
|
chat_default
|
|
9179
9222
|
};
|
|
9180
|
-
//# sourceMappingURL=chunk-
|
|
9223
|
+
//# sourceMappingURL=chunk-N7GCS2BH.mjs.map
|