@xopcai/xopc 0.0.229 → 0.0.230
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CsFAJTIN.js → agent-avatar-dicebear-Bp_wmuGW.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-DA4b6_0C.js → agents-CKG93dlc.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-7KcMWuah.js → app-management-settings-panel-CwAPK4Jm.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Cqlw7Fif.js → appearance-settings-DsGLvqTb.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-CsnhdGZ2.js → apps-page-Ee9qOQEx.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-q4pDpqkF.js → attachment-load-B4qqigAQ.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BuTqjKGX.js → automations-page-B8ImehSW.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-CD0E2ThS.js → automations-workspace-BNFAfNwC.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DUce1Bsc.js → binary-plugins-DaJbyYc2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D8Ejp-QR.js → block-editor-Kl25XWJc.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-CY1k3MMd.js → browser-settings-page-Cg6NgwE_.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-BDvZbR9v.js → browser-workflows-page-DjMxs33B.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-D1VfotHQ.js → capabilities-settings-panel-NvJKgF1u.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-DXHqRLpU.js → capability-presets-settings-panel-C2uBdALe.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-DrFL57M_.js → channels-settings-CIcYKMEs.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-h1CKexNz.js → chat-terminal-dock-BiU_4Rq6.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-DUAyfFCF.js → connectors-page-CEEcmUiP.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-DlaQQOId.js → cron-expression-Cs_5pUPT.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-8R1sXJKb.js → date-picker-y1kWrFVU.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CWur0821.js → dependency-picker-skc62zrn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CAQMLVtd.js → desktop-pet-settings-BVVCBgYK.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Knl-zNDU.js → desktop-pet-ux9DxchT.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Caaz4Rw5.js → directory-picker-path-field-V8vZP0Dy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-B965Mc15.js → extension-debug-page-Dh6DDuvQ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C0UnkBi5.js → extension-page-8OKQDEat.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BUSIAZCR.js → extension-settings-page-BgSV0Nny.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DkH0eEgy.js → gateway-config-api-Dlc6eaTG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-BBgLDm6I.js → gateway-settings-DqQgiAUv.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BtEHVXWD.js → heartbeat-settings-Pxqk5GFH.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-5SU2TNJj.js → home-page-1xjo6wE4.js} +1 -1
- package/dist/gateway/static/root/assets/{index-BNWhgmjs.js → index-Bbd_dXui.js} +17 -17
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CsRz8NrS.js → keyboard-shortcuts-settings-BSFNqxzY.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DYPEUgpP.js → local-app-workbench-page-heQ4-PJ7.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-CTBNUG4a.js → local-apps-page-DzU6yZ9-.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-B0P7rG2B.js → logs-page-BblnS6Jy.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-YqUAEwQo.js → management-settings-B8hM56HS.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-dxpSCXb8.js → markdown-split-DRbZjxMK.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CJ00i1Lg.js → media-plugins-B8vMe5VX.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-DEnbnkIt.js → notes-page-B-YZ7iuK.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-DmVYu_Oc.js → notes-workbench-CAM09C8b.js} +2 -2
- package/dist/gateway/static/root/assets/{product-open-page-BHxo9U95.js → product-open-page-DkWcyki5.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-DV2nGmsq.js → project-detail-page-BIPIwgU2.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-BNIFwFfc.js → projects-page-B_kzTn1K.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-DLXqKiA_.js → remote-access-hub-CtD8DsD-.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BpQ2GI-0.js → runtime-tools-settings-panel-Bq_ETeal.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-HE1G26Lx.js → schema-form-BogTlrsP.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-DWaXf_25.js → sessions-page-B8n9HI1y.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-xlhdRTME.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CXAn0Xhy.js → settings-form-section-Coy1Cbp6.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DsFu7Bcv.js → settings-loading-skeleton-B5GU7iCG.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C4iib9nO.js → settings-page-Dd-BRu12.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-BA83Wr1d.js → setup-status-panel-CwEFAVWx.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-BOGl3s6M.js → share-preview-page-DzXw9UQJ.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-Q2MdGaBi.js → shares-settings-Bk6UQOwS.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-cFtfVeFU.js → skill-reload-api-DrmQZ3Au.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-CdaFtNw9.js → skills-page-Brxb6QnW.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DYaAddUL.js → skills-page.utils-FB5LtEGm.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-Co7gilRd.js → system-settings-panel-ChosWt8n.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-5B1pswu8.js → task-detail-page-CW2sJbdc.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DnnZtMpA.js → use-autosave-2SqnmSKD.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-Dr1FKjXv.js → user-context-page-Bq9KB-Oj.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-wetUpi3i.js → voice-api-key-field-DtTIF6M8.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-tbTWASJJ.js → work-discovery-overlay-CK3aZDdE.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Dy0fDs8w.js → workflow-run-setup-panel-BjOuddkX.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-IVP3GSkI.js → workflows-page-CcbGEQol.js} +1 -1
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +4 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -0
- package/dist/src/agent/service/webchat-tts.js +15 -2
- package/dist/src/agent/tools/tts-tool.js +19 -13
- package/dist/src/gateway/chat-stream/mapper.js +11 -0
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-JFCbnCL2.js +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { queueEmbeddedSteer } from "../embedded/runs.js";
|
|
2
2
|
import { buildDirectUserMessageContent } from "../service/build-direct-message-content.js";
|
|
3
|
+
import { maybeEmitWebchatTts } from "../service/webchat-tts.js";
|
|
3
4
|
import { runProcessDirectStreaming } from "../service/process-direct-streaming.js";
|
|
4
5
|
import { runProcessDirect } from "../service/process-direct-one-shot.js";
|
|
5
|
-
import { maybeEmitWebchatTts } from "../service/webchat-tts.js";
|
|
6
6
|
//#region src/agent/inbound/turn-dispatcher.ts
|
|
7
7
|
var TurnDispatcher = class {
|
|
8
8
|
cfg;
|
|
@@ -13,6 +13,7 @@ import { isSessionSourceBinding, summarizeSourceContext } from "../source-contex
|
|
|
13
13
|
import { injectSourceContextsIntoUserMessage } from "../source-context/injector.js";
|
|
14
14
|
import { AsyncQueue, AsyncQueueOverflowError } from "./async-queue.js";
|
|
15
15
|
import { hydratePerTurnState, runDirectAgentTurn, tryRunSlashCommand } from "./direct-turn-helpers.js";
|
|
16
|
+
import { isSuccessfulWebchatTtsToolEvent } from "./webchat-tts.js";
|
|
16
17
|
//#region src/agent/service/process-direct-streaming.ts
|
|
17
18
|
const MAX_BUFFERED_STREAM_EVENTS = 512;
|
|
18
19
|
const LOSSY_STREAM_EVENT_TYPES = new Set([
|
|
@@ -151,6 +152,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
151
152
|
let userAborted = false;
|
|
152
153
|
let abortHandled = false;
|
|
153
154
|
let inboundVoice = false;
|
|
155
|
+
let explicitTtsEmitted = false;
|
|
154
156
|
let ranSlashCommand = false;
|
|
155
157
|
let mergedUserText = input.content;
|
|
156
158
|
let webchatSlashReceipt;
|
|
@@ -299,6 +301,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
299
301
|
runId: input.runId,
|
|
300
302
|
onEvent: (embeddedEvent) => {
|
|
301
303
|
const event = { ...embeddedEvent };
|
|
304
|
+
if (isSuccessfulWebchatTtsToolEvent(event)) explicitTtsEmitted = true;
|
|
302
305
|
if (event.type === "error" && typeof event.content === "string") event.content = formatStreamError(event.content);
|
|
303
306
|
pushVisible(event);
|
|
304
307
|
}
|
|
@@ -329,7 +332,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
329
332
|
sessionKey,
|
|
330
333
|
droppedEvents: queue.droppedCount
|
|
331
334
|
}, "Coalesced stream progress events because the consumer fell behind");
|
|
332
|
-
if (!userAborted && !streamOverflowed && channel === "webchat") try {
|
|
335
|
+
if (!userAborted && !streamOverflowed && channel === "webchat" && !explicitTtsEmitted) try {
|
|
333
336
|
const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);
|
|
334
337
|
if (ttsAudioEvent) queue.push(ttsAudioEvent);
|
|
335
338
|
} catch (ttsErr) {
|
|
@@ -15,6 +15,8 @@ export type WebchatTtsDeps = {
|
|
|
15
15
|
warn: (obj: Record<string, unknown>, msg: string) => void;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
+
/** True when the explicit TTS tool already produced durable Webchat audio. */
|
|
19
|
+
export declare function isSuccessfulWebchatTtsToolEvent(event: unknown): boolean;
|
|
18
20
|
/**
|
|
19
21
|
* Generate TTS for webchat when config allows; persist under `{stateDir}/media/tts/`.
|
|
20
22
|
*/
|
|
@@ -3,9 +3,22 @@ import { speak } from "../../voice/tts/speak-core.js";
|
|
|
3
3
|
import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
|
|
4
4
|
import { getChannelOutputFormat, shouldUseTTS } from "../../voice/tts/service.js";
|
|
5
5
|
import { compressAudio } from "../../voice/tts/audio.js";
|
|
6
|
-
import "../../voice/tts/index.js";
|
|
7
6
|
import { persistOutboundTtsAudio } from "../../channels/attachments/outbound-tts-persist.js";
|
|
7
|
+
import "../../voice/tts/index.js";
|
|
8
8
|
//#region src/agent/service/webchat-tts.ts
|
|
9
|
+
/** True when the explicit TTS tool already produced durable Webchat audio. */
|
|
10
|
+
function isSuccessfulWebchatTtsToolEvent(event) {
|
|
11
|
+
if (!event || typeof event !== "object" || Array.isArray(event)) return false;
|
|
12
|
+
const row = event;
|
|
13
|
+
if (row.type !== "tool_execution_end" || row.toolName !== "text_to_speech" || row.isError === true) return false;
|
|
14
|
+
const result = row.result && typeof row.result === "object" && !Array.isArray(row.result) ? row.result : null;
|
|
15
|
+
const details = result?.details && typeof result.details === "object" && !Array.isArray(result.details) ? result.details : null;
|
|
16
|
+
return Array.isArray(details?.media) && details.media.some((item) => {
|
|
17
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return false;
|
|
18
|
+
const media = item;
|
|
19
|
+
return typeof media.uri === "string" && media.uri.trim().length > 0;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
9
22
|
/**
|
|
10
23
|
* Generate TTS for webchat when config allows; persist under `{stateDir}/media/tts/`.
|
|
11
24
|
*/
|
|
@@ -57,4 +70,4 @@ async function appendMediaToLastAssistant(sessionStore, sessionKey, ref) {
|
|
|
57
70
|
}
|
|
58
71
|
}
|
|
59
72
|
//#endregion
|
|
60
|
-
export { appendMediaToLastAssistant, maybeEmitWebchatTts };
|
|
73
|
+
export { appendMediaToLastAssistant, isSuccessfulWebchatTtsToolEvent, maybeEmitWebchatTts };
|
|
@@ -4,6 +4,7 @@ import { speak } from "../../voice/tts/speak-core.js";
|
|
|
4
4
|
import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
|
|
5
5
|
import { getChannelOutputFormat } from "../../voice/tts/service.js";
|
|
6
6
|
import { compressAudio } from "../../voice/tts/audio.js";
|
|
7
|
+
import { persistOutboundTtsAudio } from "../../channels/attachments/outbound-tts-persist.js";
|
|
7
8
|
import { Type } from "@sinclair/typebox";
|
|
8
9
|
//#region src/agent/tools/tts-tool.ts
|
|
9
10
|
init_logger();
|
|
@@ -72,30 +73,35 @@ function createTextToSpeechTool(deps) {
|
|
|
72
73
|
});
|
|
73
74
|
const wavTarget = outFmt.format === "mp3" ? "mp3" : "opus";
|
|
74
75
|
const { buffer: compressedAudio, format: compressedFormat } = await compressAudio(Buffer.from(result.audio), result.format, wavTarget);
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
const mimeType = compressedFormat === "opus" ? "audio/ogg" : compressedFormat === "mp3" || compressedFormat === "mpeg" ? "audio/mpeg" : `audio/${compressedFormat}`;
|
|
77
|
+
const media = ctx.channel === "webchat" ? await persistOutboundTtsAudio(compressedAudio, compressedFormat) : void 0;
|
|
78
|
+
if (!media) {
|
|
79
|
+
const msg = {
|
|
80
|
+
channel: ctx.channel,
|
|
81
|
+
chat_id: ctx.chatId,
|
|
82
|
+
content: "",
|
|
83
|
+
mediaUrl: `data:${mimeType};base64,${compressedAudio.toString("base64")}`,
|
|
84
|
+
mediaType: "audio",
|
|
85
|
+
audioAsVoice: outFmt.voiceCompatible
|
|
86
|
+
};
|
|
87
|
+
await deps.bus.publishOutbound(msg);
|
|
88
|
+
}
|
|
85
89
|
log.info({
|
|
86
90
|
provider: result.provider,
|
|
87
91
|
format: compressedFormat,
|
|
92
|
+
channel: ctx.channel,
|
|
88
93
|
textLength: params.text.length,
|
|
89
94
|
audioSize: compressedAudio.length
|
|
90
|
-
}, "TTS tool sent audio");
|
|
95
|
+
}, ctx.channel === "webchat" ? "TTS tool attached audio" : "TTS tool sent audio");
|
|
91
96
|
return {
|
|
92
97
|
content: [{
|
|
93
98
|
type: "text",
|
|
94
|
-
text: `✅ Sent voice message (${result.provider}, ${compressedFormat}).`
|
|
99
|
+
text: ctx.channel === "webchat" ? `✅ Attached voice message (${result.provider}, ${compressedFormat}).` : `✅ Sent voice message (${result.provider}, ${compressedFormat}).`
|
|
95
100
|
}],
|
|
96
101
|
details: {
|
|
97
102
|
provider: result.provider,
|
|
98
|
-
format: compressedFormat
|
|
103
|
+
format: compressedFormat,
|
|
104
|
+
...media ? { media: [media] } : {}
|
|
99
105
|
}
|
|
100
106
|
};
|
|
101
107
|
} catch (error) {
|
|
@@ -342,6 +342,17 @@ var ChatStreamMapper = class {
|
|
|
342
342
|
errorMessage: event.isError ? result?.text ?? extractText(result?.content) : void 0
|
|
343
343
|
})];
|
|
344
344
|
const details = asRecord(fullResult?.details);
|
|
345
|
+
if (toolName === "text_to_speech" && !event.isError && details) {
|
|
346
|
+
const audio = (Array.isArray(details.media) ? details.media : []).map(asRecord).find((item) => item?.type === "voice" || String(item?.mimeType ?? "").startsWith("audio/"));
|
|
347
|
+
const uri = typeof audio?.uri === "string" ? audio.uri.trim() : "";
|
|
348
|
+
if (uri) events.push(this.make("tts_audio", {
|
|
349
|
+
uri,
|
|
350
|
+
mimeType: typeof audio?.mimeType === "string" ? audio.mimeType : "audio/mpeg",
|
|
351
|
+
name: typeof audio?.name === "string" ? audio.name : "voice.mp3",
|
|
352
|
+
attachTo: "last_assistant",
|
|
353
|
+
messageId
|
|
354
|
+
}));
|
|
355
|
+
}
|
|
345
356
|
if (toolName === "exec_command" && details) events.push(this.make("command_completed", {
|
|
346
357
|
messageId,
|
|
347
358
|
toolCallId,
|
|
@@ -14,8 +14,8 @@ import "../../../voice/stt/index.js";
|
|
|
14
14
|
import { listSttProvidersForApi } from "../../../voice/stt/list-providers.js";
|
|
15
15
|
import "../../../voice/tts/index.js";
|
|
16
16
|
import { createGatewayRouteLogger } from "../lib/route-logger.js";
|
|
17
|
-
import { listLocalVoiceModelStatuses, removeLocalVoiceModel, startLocalVoiceModelInstall } from "../../../voice/local/model-manager.js";
|
|
18
17
|
import { listTtsProvidersForApi } from "../../../voice/tts/list-providers.js";
|
|
18
|
+
import { listLocalVoiceModelStatuses, removeLocalVoiceModel, startLocalVoiceModelInstall } from "../../../voice/local/model-manager.js";
|
|
19
19
|
//#region src/gateway/hono/routes/voice.ts
|
|
20
20
|
init_providers();
|
|
21
21
|
const log = createGatewayRouteLogger("Voice");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.230",
|
|
4
4
|
"description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Or as e}from"./index-BNWhgmjs.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};
|