@desktalk/core 0.1.0-alpha.1
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/LICENSE +21 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +82 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/frontend/assets/frontend-B3QNYf3p.js +413 -0
- package/dist/frontend/assets/frontend-B3QNYf3p.js.map +1 -0
- package/dist/frontend/assets/frontend-B4aeXn9d.js +416 -0
- package/dist/frontend/assets/frontend-B4aeXn9d.js.map +1 -0
- package/dist/frontend/assets/frontend-BwyRSlHp.js +6513 -0
- package/dist/frontend/assets/frontend-BwyRSlHp.js.map +1 -0
- package/dist/frontend/assets/frontend-Dix2OWTT.js +229 -0
- package/dist/frontend/assets/frontend-Dix2OWTT.js.map +1 -0
- package/dist/frontend/assets/frontend-Dx41dEM9.js +407 -0
- package/dist/frontend/assets/frontend-Dx41dEM9.js.map +1 -0
- package/dist/frontend/assets/frontend-WpQng8Mt.js +1991 -0
- package/dist/frontend/assets/frontend-WpQng8Mt.js.map +1 -0
- package/dist/frontend/assets/frontend-rTwBdJbn.js +2123 -0
- package/dist/frontend/assets/frontend-rTwBdJbn.js.map +1 -0
- package/dist/frontend/assets/highlighted-body-TPN3WLV5-DD4wpkf4.js +2 -0
- package/dist/frontend/assets/highlighted-body-TPN3WLV5-DD4wpkf4.js.map +1 -0
- package/dist/frontend/assets/index-C5-XUOS7.js +1863 -0
- package/dist/frontend/assets/index-C5-XUOS7.js.map +1 -0
- package/dist/frontend/assets/index-C_e3_6yE.css +1 -0
- package/dist/frontend/index.html +22 -0
- package/dist/frontend/pcm-capture-processor.js +65 -0
- package/dist/i18n/manifest.json +34 -0
- package/dist/i18n/zh-CN.json +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server/admin-routes.d.ts +14 -0
- package/dist/server/admin-routes.d.ts.map +1 -0
- package/dist/server/admin-routes.js +118 -0
- package/dist/server/admin-routes.js.map +1 -0
- package/dist/server/api-routes.d.ts +8 -0
- package/dist/server/api-routes.d.ts.map +1 -0
- package/dist/server/api-routes.js +203 -0
- package/dist/server/api-routes.js.map +1 -0
- package/dist/server/auth-routes.d.ts +19 -0
- package/dist/server/auth-routes.d.ts.map +1 -0
- package/dist/server/auth-routes.js +155 -0
- package/dist/server/auth-routes.js.map +1 -0
- package/dist/server/dtfs-routes.d.ts +3 -0
- package/dist/server/dtfs-routes.d.ts.map +1 -0
- package/dist/server/dtfs-routes.js +183 -0
- package/dist/server/dtfs-routes.js.map +1 -0
- package/dist/server/index.d.ts +15 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +158 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/monaco-routes.d.ts +3 -0
- package/dist/server/monaco-routes.d.ts.map +1 -0
- package/dist/server/monaco-routes.js +45 -0
- package/dist/server/monaco-routes.js.map +1 -0
- package/dist/server/voice-routes.d.ts +7 -0
- package/dist/server/voice-routes.d.ts.map +1 -0
- package/dist/server/voice-routes.js +142 -0
- package/dist/server/voice-routes.js.map +1 -0
- package/dist/server/ws-routes.d.ts +29 -0
- package/dist/server/ws-routes.d.ts.map +1 -0
- package/dist/server/ws-routes.js +334 -0
- package/dist/server/ws-routes.js.map +1 -0
- package/dist/services/ai/action-tool.d.ts +9 -0
- package/dist/services/ai/action-tool.d.ts.map +1 -0
- package/dist/services/ai/action-tool.js +51 -0
- package/dist/services/ai/action-tool.js.map +1 -0
- package/dist/services/ai/app-tools.d.ts +15 -0
- package/dist/services/ai/app-tools.d.ts.map +1 -0
- package/dist/services/ai/app-tools.js +119 -0
- package/dist/services/ai/app-tools.js.map +1 -0
- package/dist/services/ai/chat-service.d.ts +27 -0
- package/dist/services/ai/chat-service.d.ts.map +1 -0
- package/dist/services/ai/chat-service.js +213 -0
- package/dist/services/ai/chat-service.js.map +1 -0
- package/dist/services/ai/create-liveapp-tool.d.ts +15 -0
- package/dist/services/ai/create-liveapp-tool.d.ts.map +1 -0
- package/dist/services/ai/create-liveapp-tool.js +142 -0
- package/dist/services/ai/create-liveapp-tool.js.map +1 -0
- package/dist/services/ai/desktop-tool.d.ts +27 -0
- package/dist/services/ai/desktop-tool.d.ts.map +1 -0
- package/dist/services/ai/desktop-tool.js +106 -0
- package/dist/services/ai/desktop-tool.js.map +1 -0
- package/dist/services/ai/edit-history.d.ts +16 -0
- package/dist/services/ai/edit-history.d.ts.map +1 -0
- package/dist/services/ai/edit-history.js +137 -0
- package/dist/services/ai/edit-history.js.map +1 -0
- package/dist/services/ai/edit-tool.d.ts +9 -0
- package/dist/services/ai/edit-tool.d.ts.map +1 -0
- package/dist/services/ai/edit-tool.js +113 -0
- package/dist/services/ai/edit-tool.js.map +1 -0
- package/dist/services/ai/generate-html-tool.d.ts +15 -0
- package/dist/services/ai/generate-html-tool.d.ts.map +1 -0
- package/dist/services/ai/generate-html-tool.js +140 -0
- package/dist/services/ai/generate-html-tool.js.map +1 -0
- package/dist/services/ai/generate-icon-tool.d.ts +10 -0
- package/dist/services/ai/generate-icon-tool.d.ts.map +1 -0
- package/dist/services/ai/generate-icon-tool.js +58 -0
- package/dist/services/ai/generate-icon-tool.js.map +1 -0
- package/dist/services/ai/html-bridge-script.d.ts +2 -0
- package/dist/services/ai/html-bridge-script.d.ts.map +1 -0
- package/dist/services/ai/html-bridge-script.js +2 -0
- package/dist/services/ai/html-bridge-script.js.map +1 -0
- package/dist/services/ai/html-guidelines-tool.d.ts +3 -0
- package/dist/services/ai/html-guidelines-tool.d.ts.map +1 -0
- package/dist/services/ai/html-guidelines-tool.js +157 -0
- package/dist/services/ai/html-guidelines-tool.js.map +1 -0
- package/dist/services/ai/html-stream-coordinator.d.ts +92 -0
- package/dist/services/ai/html-stream-coordinator.d.ts.map +1 -0
- package/dist/services/ai/html-stream-coordinator.js +314 -0
- package/dist/services/ai/html-stream-coordinator.js.map +1 -0
- package/dist/services/ai/html-theme-link.d.ts +9 -0
- package/dist/services/ai/html-theme-link.d.ts.map +1 -0
- package/dist/services/ai/html-theme-link.js +12 -0
- package/dist/services/ai/html-theme-link.js.map +1 -0
- package/dist/services/ai/html-ui-script.d.ts +9 -0
- package/dist/services/ai/html-ui-script.d.ts.map +1 -0
- package/dist/services/ai/html-ui-script.js +9 -0
- package/dist/services/ai/html-ui-script.js.map +1 -0
- package/dist/services/ai/image-generation-service.d.ts +26 -0
- package/dist/services/ai/image-generation-service.d.ts.map +1 -0
- package/dist/services/ai/image-generation-service.js +205 -0
- package/dist/services/ai/image-generation-service.js.map +1 -0
- package/dist/services/ai/manual-pages/desktop-actions.md +36 -0
- package/dist/services/ai/manual-pages/desktop-windows.md +24 -0
- package/dist/services/ai/manual-pages/dt-badge.md +36 -0
- package/dist/services/ai/manual-pages/dt-button.md +38 -0
- package/dist/services/ai/manual-pages/dt-card.md +22 -0
- package/dist/services/ai/manual-pages/dt-chart.md +261 -0
- package/dist/services/ai/manual-pages/dt-divider.md +25 -0
- package/dist/services/ai/manual-pages/dt-grid.md +29 -0
- package/dist/services/ai/manual-pages/dt-list-view.md +96 -0
- package/dist/services/ai/manual-pages/dt-markdown-editor.md +90 -0
- package/dist/services/ai/manual-pages/dt-markdown.md +86 -0
- package/dist/services/ai/manual-pages/dt-select.md +21 -0
- package/dist/services/ai/manual-pages/dt-stack.md +31 -0
- package/dist/services/ai/manual-pages/dt-stat.md +43 -0
- package/dist/services/ai/manual-pages/dt-table-view.md +120 -0
- package/dist/services/ai/manual-pages/dt-tooltip.md +18 -0
- package/dist/services/ai/manual-pages/editing-preview.md +25 -0
- package/dist/services/ai/manual-pages/html-actions.md +74 -0
- package/dist/services/ai/manual-pages/html-bridge.md +187 -0
- package/dist/services/ai/manual-pages/html-components.md +66 -0
- package/dist/services/ai/manual-pages/html-examples.md +185 -0
- package/dist/services/ai/manual-pages/html-layouts.md +128 -0
- package/dist/services/ai/manual-pages/html-storage.md +153 -0
- package/dist/services/ai/manual-pages/html-tokens.md +26 -0
- package/dist/services/ai/manual-pages/index.d.ts +10 -0
- package/dist/services/ai/manual-pages/index.d.ts.map +1 -0
- package/dist/services/ai/manual-pages/index.js +186 -0
- package/dist/services/ai/manual-pages/index.js.map +1 -0
- package/dist/services/ai/manual-tool.d.ts +3 -0
- package/dist/services/ai/manual-tool.d.ts.map +1 -0
- package/dist/services/ai/manual-tool.js +104 -0
- package/dist/services/ai/manual-tool.js.map +1 -0
- package/dist/services/ai/pi-session-service.d.ts +101 -0
- package/dist/services/ai/pi-session-service.d.ts.map +1 -0
- package/dist/services/ai/pi-session-service.js +697 -0
- package/dist/services/ai/pi-session-service.js.map +1 -0
- package/dist/services/ai/providers.d.ts +21 -0
- package/dist/services/ai/providers.d.ts.map +1 -0
- package/dist/services/ai/providers.js +93 -0
- package/dist/services/ai/providers.js.map +1 -0
- package/dist/services/ai/redo-edit-tool.d.ts +9 -0
- package/dist/services/ai/redo-edit-tool.d.ts.map +1 -0
- package/dist/services/ai/redo-edit-tool.js +44 -0
- package/dist/services/ai/redo-edit-tool.js.map +1 -0
- package/dist/services/ai/system-prompt.d.ts +7 -0
- package/dist/services/ai/system-prompt.d.ts.map +1 -0
- package/dist/services/ai/system-prompt.js +72 -0
- package/dist/services/ai/system-prompt.js.map +1 -0
- package/dist/services/ai/undo-edit-tool.d.ts +9 -0
- package/dist/services/ai/undo-edit-tool.d.ts.map +1 -0
- package/dist/services/ai/undo-edit-tool.js +44 -0
- package/dist/services/ai/undo-edit-tool.js.map +1 -0
- package/dist/services/ai/window-tools.d.ts +27 -0
- package/dist/services/ai/window-tools.d.ts.map +1 -0
- package/dist/services/ai/window-tools.js +155 -0
- package/dist/services/ai/window-tools.js.map +1 -0
- package/dist/services/backend-host.d.ts +10 -0
- package/dist/services/backend-host.d.ts.map +1 -0
- package/dist/services/backend-host.js +117 -0
- package/dist/services/backend-host.js.map +1 -0
- package/dist/services/backend-ipc.d.ts +60 -0
- package/dist/services/backend-ipc.d.ts.map +1 -0
- package/dist/services/backend-ipc.js +2 -0
- package/dist/services/backend-ipc.js.map +1 -0
- package/dist/services/backend-process-manager.d.ts +60 -0
- package/dist/services/backend-process-manager.d.ts.map +1 -0
- package/dist/services/backend-process-manager.js +203 -0
- package/dist/services/backend-process-manager.js.map +1 -0
- package/dist/services/filesystem.d.ts +8 -0
- package/dist/services/filesystem.d.ts.map +1 -0
- package/dist/services/filesystem.js +94 -0
- package/dist/services/filesystem.js.map +1 -0
- package/dist/services/i18n.d.ts +28 -0
- package/dist/services/i18n.d.ts.map +1 -0
- package/dist/services/i18n.js +76 -0
- package/dist/services/i18n.js.map +1 -0
- package/dist/services/liveapp-icon.d.ts +9 -0
- package/dist/services/liveapp-icon.d.ts.map +1 -0
- package/dist/services/liveapp-icon.js +28 -0
- package/dist/services/liveapp-icon.js.map +1 -0
- package/dist/services/liveapps.d.ts +12 -0
- package/dist/services/liveapps.d.ts.map +1 -0
- package/dist/services/liveapps.js +84 -0
- package/dist/services/liveapps.js.map +1 -0
- package/dist/services/logger.d.ts +34 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +74 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/messaging.d.ts +14 -0
- package/dist/services/messaging.d.ts.map +1 -0
- package/dist/services/messaging.js +41 -0
- package/dist/services/messaging.js.map +1 -0
- package/dist/services/miniapp-icon.d.ts +9 -0
- package/dist/services/miniapp-icon.d.ts.map +1 -0
- package/dist/services/miniapp-icon.js +25 -0
- package/dist/services/miniapp-icon.js.map +1 -0
- package/dist/services/miniapp-registry.d.ts +73 -0
- package/dist/services/miniapp-registry.d.ts.map +1 -0
- package/dist/services/miniapp-registry.js +144 -0
- package/dist/services/miniapp-registry.js.map +1 -0
- package/dist/services/onboarding-config.d.ts +37 -0
- package/dist/services/onboarding-config.d.ts.map +1 -0
- package/dist/services/onboarding-config.js +76 -0
- package/dist/services/onboarding-config.js.map +1 -0
- package/dist/services/preferences.d.ts +10 -0
- package/dist/services/preferences.d.ts.map +1 -0
- package/dist/services/preferences.js +48 -0
- package/dist/services/preferences.js.map +1 -0
- package/dist/services/proxy-dispatcher.d.ts +18 -0
- package/dist/services/proxy-dispatcher.d.ts.map +1 -0
- package/dist/services/proxy-dispatcher.js +33 -0
- package/dist/services/proxy-dispatcher.js.map +1 -0
- package/dist/services/storage.d.ts +7 -0
- package/dist/services/storage.d.ts.map +1 -0
- package/dist/services/storage.js +55 -0
- package/dist/services/storage.js.map +1 -0
- package/dist/services/theme-css.d.ts +21 -0
- package/dist/services/theme-css.d.ts.map +1 -0
- package/dist/services/theme-css.js +213 -0
- package/dist/services/theme-css.js.map +1 -0
- package/dist/services/user-db.d.ts +69 -0
- package/dist/services/user-db.d.ts.map +1 -0
- package/dist/services/user-db.js +175 -0
- package/dist/services/user-db.js.map +1 -0
- package/dist/services/voice/audio-format.d.ts +5 -0
- package/dist/services/voice/audio-format.d.ts.map +1 -0
- package/dist/services/voice/audio-format.js +27 -0
- package/dist/services/voice/audio-format.js.map +1 -0
- package/dist/services/voice/azure-openai-whisper-adapter.d.ts +23 -0
- package/dist/services/voice/azure-openai-whisper-adapter.d.ts.map +1 -0
- package/dist/services/voice/azure-openai-whisper-adapter.js +60 -0
- package/dist/services/voice/azure-openai-whisper-adapter.js.map +1 -0
- package/dist/services/voice/openai-whisper-adapter.d.ts +22 -0
- package/dist/services/voice/openai-whisper-adapter.d.ts.map +1 -0
- package/dist/services/voice/openai-whisper-adapter.js +61 -0
- package/dist/services/voice/openai-whisper-adapter.js.map +1 -0
- package/dist/services/voice/stt-adapter.d.ts +31 -0
- package/dist/services/voice/stt-adapter.d.ts.map +1 -0
- package/dist/services/voice/stt-adapter.js +8 -0
- package/dist/services/voice/stt-adapter.js.map +1 -0
- package/dist/services/voice/vad-segmenter.d.ts +68 -0
- package/dist/services/voice/vad-segmenter.d.ts.map +1 -0
- package/dist/services/voice/vad-segmenter.js +159 -0
- package/dist/services/voice/vad-segmenter.js.map +1 -0
- package/dist/services/voice/voice-session.d.ts +54 -0
- package/dist/services/voice/voice-session.d.ts.map +1 -0
- package/dist/services/voice/voice-session.js +137 -0
- package/dist/services/voice/voice-session.js.map +1 -0
- package/dist/services/window-manager.d.ts +94 -0
- package/dist/services/window-manager.d.ts.map +1 -0
- package/dist/services/window-manager.js +282 -0
- package/dist/services/window-manager.js.map +1 -0
- package/dist/services/workspace.d.ts +51 -0
- package/dist/services/workspace.d.ts.map +1 -0
- package/dist/services/workspace.js +144 -0
- package/dist/services/workspace.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { getStoredPreference } from '../services/preferences.js';
|
|
2
|
+
import { VoiceSession } from '../services/voice/voice-session.js';
|
|
3
|
+
import { AzureOpenAIWhisperAdapter } from '../services/voice/azure-openai-whisper-adapter.js';
|
|
4
|
+
import { OpenAIWhisperAdapter } from '../services/voice/openai-whisper-adapter.js';
|
|
5
|
+
async function getPreference(key) {
|
|
6
|
+
return getStoredPreference(key);
|
|
7
|
+
}
|
|
8
|
+
async function createSttAdapter() {
|
|
9
|
+
const provider = (await getPreference('voice.defaultProvider')) ??
|
|
10
|
+
(await getPreference('voice.provider')) ??
|
|
11
|
+
'openai-whisper';
|
|
12
|
+
const providerPrefix = `voice.providers.${provider}`;
|
|
13
|
+
const apiKey = (await getPreference(`${providerPrefix}.apiKey`)) ??
|
|
14
|
+
(await getPreference('voice.apiKey'));
|
|
15
|
+
if (!apiKey)
|
|
16
|
+
return null;
|
|
17
|
+
if (provider === 'openai-whisper') {
|
|
18
|
+
const model = (await getPreference(`${providerPrefix}.model`)) ??
|
|
19
|
+
(await getPreference('voice.model')) ??
|
|
20
|
+
'whisper-1';
|
|
21
|
+
const baseUrl = (await getPreference(`${providerPrefix}.baseUrl`)) ??
|
|
22
|
+
(await getPreference('voice.baseUrl')) ??
|
|
23
|
+
'https://api.openai.com/v1';
|
|
24
|
+
return new OpenAIWhisperAdapter({ apiKey, model, baseUrl });
|
|
25
|
+
}
|
|
26
|
+
if (provider === 'azure-openai-whisper') {
|
|
27
|
+
const endpoint = (await getPreference(`${providerPrefix}.baseUrl`)) ??
|
|
28
|
+
(await getPreference('voice.baseUrl'));
|
|
29
|
+
const deployment = (await getPreference(`${providerPrefix}.azureDeployment`)) ??
|
|
30
|
+
(await getPreference('voice.azureDeployment'));
|
|
31
|
+
const apiVersion = (await getPreference(`${providerPrefix}.azureApiVersion`)) ??
|
|
32
|
+
(await getPreference('voice.azureApiVersion')) ??
|
|
33
|
+
'2024-06-01';
|
|
34
|
+
if (!endpoint || !deployment) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return new AzureOpenAIWhisperAdapter({
|
|
38
|
+
apiKey,
|
|
39
|
+
endpoint,
|
|
40
|
+
deployment,
|
|
41
|
+
apiVersion,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
async function getVadConfigFromPreferences() {
|
|
47
|
+
const silenceTimeoutMs = (await getPreference('voice.silenceTimeoutMs'));
|
|
48
|
+
const energyThreshold = (await getPreference('voice.energyThreshold'));
|
|
49
|
+
return {
|
|
50
|
+
...(silenceTimeoutMs !== undefined ? { silenceTimeoutMs } : {}),
|
|
51
|
+
...(energyThreshold !== undefined ? { energyThreshold } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export async function voiceRoutes(app, options) {
|
|
55
|
+
const voiceSessions = new Map();
|
|
56
|
+
const voiceLog = options.logger.child({ scope: 'voice' });
|
|
57
|
+
app.get('/ws/voice', { websocket: true }, (socket) => {
|
|
58
|
+
let session = null;
|
|
59
|
+
socket.on('message', async (raw) => {
|
|
60
|
+
if (Buffer.isBuffer(raw) || raw instanceof ArrayBuffer) {
|
|
61
|
+
let isJson = false;
|
|
62
|
+
try {
|
|
63
|
+
const str = Buffer.isBuffer(raw)
|
|
64
|
+
? raw.toString('utf-8')
|
|
65
|
+
: Buffer.from(raw).toString('utf-8');
|
|
66
|
+
if (str.length > 0 && str[0] === '{') {
|
|
67
|
+
const msg = JSON.parse(str);
|
|
68
|
+
isJson = true;
|
|
69
|
+
await handleVoiceControlMessage(msg);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Not JSON, treat as binary audio.
|
|
74
|
+
}
|
|
75
|
+
if (!isJson && session) {
|
|
76
|
+
const buf = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
|
|
77
|
+
await session.processAudioChunk(buf);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(raw) && session) {
|
|
82
|
+
const buf = Buffer.concat(raw);
|
|
83
|
+
await session.processAudioChunk(buf);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
async function handleVoiceControlMessage(msg) {
|
|
87
|
+
if (msg.type === 'session.start') {
|
|
88
|
+
const sessionId = msg.sessionId;
|
|
89
|
+
const sampleRate = msg.sampleRate ?? 16000;
|
|
90
|
+
const channels = msg.channels ?? 1;
|
|
91
|
+
const format = msg.format ?? 'pcm_s16le';
|
|
92
|
+
const prefLanguage = (await getPreference('general.language'));
|
|
93
|
+
const language = msg.language ?? prefLanguage;
|
|
94
|
+
const adapter = await createSttAdapter();
|
|
95
|
+
if (!adapter) {
|
|
96
|
+
socket.send(JSON.stringify({
|
|
97
|
+
type: 'error',
|
|
98
|
+
sessionId,
|
|
99
|
+
code: 'NO_STT_PROVIDER',
|
|
100
|
+
message: 'No STT provider configured. Check Preferences -> Voice for provider credentials.',
|
|
101
|
+
}));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const vadConfig = await getVadConfigFromPreferences();
|
|
105
|
+
session = new VoiceSession(sessionId, socket, adapter, {
|
|
106
|
+
sampleRate,
|
|
107
|
+
channels,
|
|
108
|
+
format,
|
|
109
|
+
vad: vadConfig,
|
|
110
|
+
language,
|
|
111
|
+
}, voiceLog.child({ sessionId }));
|
|
112
|
+
voiceSessions.set(sessionId, session);
|
|
113
|
+
voiceLog.info({ sessionId, format, sampleRate, channels, language }, 'voice session started');
|
|
114
|
+
socket.send(JSON.stringify({
|
|
115
|
+
type: 'session.ready',
|
|
116
|
+
sessionId,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
else if (msg.type === 'session.end') {
|
|
120
|
+
const sessionId = msg.sessionId;
|
|
121
|
+
if (session) {
|
|
122
|
+
session.close();
|
|
123
|
+
voiceSessions.delete(session.sessionId);
|
|
124
|
+
session = null;
|
|
125
|
+
}
|
|
126
|
+
voiceLog.info({ sessionId }, 'voice session ended by client');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
socket.on('close', () => {
|
|
130
|
+
if (session) {
|
|
131
|
+
voiceLog.info({ sessionId: session.sessionId }, 'voice session closed (connection lost)');
|
|
132
|
+
voiceSessions.delete(session.sessionId);
|
|
133
|
+
session.close();
|
|
134
|
+
session = null;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
socket.on('error', (err) => {
|
|
138
|
+
voiceLog.error({ err: err.message }, 'voice WebSocket error');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=voice-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-routes.js","sourceRoot":"","sources":["../../src/server/voice-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type pino from 'pino';
|
|
3
|
+
import type { PiSessionService } from '../services/ai/pi-session-service.js';
|
|
4
|
+
import { type WindowManagerService } from '../services/window-manager.js';
|
|
5
|
+
type PendingWindowActionRequest = {
|
|
6
|
+
resolve: (value: unknown) => void;
|
|
7
|
+
reject: (reason?: unknown) => void;
|
|
8
|
+
timeout: ReturnType<typeof setTimeout>;
|
|
9
|
+
};
|
|
10
|
+
type PendingAiCommandRequest = {
|
|
11
|
+
resolve: (value: {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
windowId?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
}) => void;
|
|
16
|
+
reject: (reason?: unknown) => void;
|
|
17
|
+
timeout: ReturnType<typeof setTimeout>;
|
|
18
|
+
};
|
|
19
|
+
export interface WsRoutesOptions {
|
|
20
|
+
logger: pino.Logger;
|
|
21
|
+
piSessionService: PiSessionService;
|
|
22
|
+
windowManager: WindowManagerService;
|
|
23
|
+
pendingWindowActionRequests: Map<string, PendingWindowActionRequest>;
|
|
24
|
+
pendingAiCommandRequests: Map<string, PendingAiCommandRequest>;
|
|
25
|
+
setCurrentWsUsername: (username: string | null) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function wsRoutes(app: FastifyInstance, options: WsRoutesOptions): Promise<void>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=ws-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-routes.d.ts","sourceRoot":"","sources":["../../src/server/ws-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAM7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC,KAAK,0BAA0B,GAAG;IAChC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CACxC,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,oBAAoB,CAAC;IACpC,2BAA2B,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IACrE,wBAAwB,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAC/D,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACzD;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA4W5F"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { addClient } from '../services/messaging.js';
|
|
3
|
+
import { registry } from '../services/miniapp-registry.js';
|
|
4
|
+
import { processManager } from '../services/backend-process-manager.js';
|
|
5
|
+
import { setPreferenceUser } from '../services/preferences.js';
|
|
6
|
+
import { getUserHomeDir, ensureUserHome } from '../services/workspace.js';
|
|
7
|
+
export async function wsRoutes(app, options) {
|
|
8
|
+
const { logger, piSessionService, windowManager, pendingWindowActionRequests, pendingAiCommandRequests, setCurrentWsUsername, } = options;
|
|
9
|
+
app.get('/ws', { websocket: true }, (socket, req) => {
|
|
10
|
+
const user = req.user;
|
|
11
|
+
if (!user) {
|
|
12
|
+
socket.close(4001, 'Authentication required');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const username = user.username;
|
|
16
|
+
setCurrentWsUsername(username);
|
|
17
|
+
addClient(socket);
|
|
18
|
+
let activeAiRequestId = null;
|
|
19
|
+
const cancelledAiRequestIds = new Set();
|
|
20
|
+
function sendAiEvent(event) {
|
|
21
|
+
socket.send(JSON.stringify({
|
|
22
|
+
type: 'ai:event',
|
|
23
|
+
event,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
void (async () => {
|
|
27
|
+
try {
|
|
28
|
+
ensureUserHome(username);
|
|
29
|
+
windowManager.switchUser(join(getUserHomeDir(username), '.storage', 'window-state.json'));
|
|
30
|
+
setPreferenceUser(username);
|
|
31
|
+
await windowManager.activatePersistedMiniApps(async (miniAppId, launchArgs) => {
|
|
32
|
+
await registry.activate(miniAppId, username, { launchArgs });
|
|
33
|
+
});
|
|
34
|
+
sendAiEvent({
|
|
35
|
+
type: 'history_sync',
|
|
36
|
+
sessionId: piSessionService.getSessionId(),
|
|
37
|
+
messages: piSessionService.getHistory(),
|
|
38
|
+
});
|
|
39
|
+
sendAiEvent({
|
|
40
|
+
type: 'sessions_sync',
|
|
41
|
+
sessionId: piSessionService.getSessionId(),
|
|
42
|
+
sessions: await piSessionService.listSessions(),
|
|
43
|
+
});
|
|
44
|
+
const persisted = windowManager.getPersistedState();
|
|
45
|
+
socket.send(JSON.stringify({
|
|
46
|
+
type: 'window:state',
|
|
47
|
+
version: persisted.version,
|
|
48
|
+
windows: persisted.windows,
|
|
49
|
+
tree: persisted.tree,
|
|
50
|
+
focusedWindowId: persisted.focusedWindowId,
|
|
51
|
+
fullscreenWindowId: persisted.fullscreenWindowId,
|
|
52
|
+
windowIdCounter: persisted.windowIdCounter,
|
|
53
|
+
nextSplitDirection: persisted.nextSplitDirection,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger.error({ username, err: error instanceof Error ? error.message : String(error) }, 'failed to restore persisted miniapps for websocket session');
|
|
58
|
+
socket.close(1011, 'Failed to restore desktop state');
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
socket.on('message', async (raw) => {
|
|
62
|
+
try {
|
|
63
|
+
const msg = JSON.parse(raw.toString());
|
|
64
|
+
if (msg.type === 'command:invoke') {
|
|
65
|
+
const { miniAppId, command, requestId, data } = msg;
|
|
66
|
+
const processKey = `${miniAppId}:${username}`;
|
|
67
|
+
try {
|
|
68
|
+
const result = await processManager.sendCommand(processKey, command, data);
|
|
69
|
+
socket.send(JSON.stringify({
|
|
70
|
+
type: 'command:response',
|
|
71
|
+
requestId,
|
|
72
|
+
data: result,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
socket.send(JSON.stringify({
|
|
77
|
+
type: 'command:response',
|
|
78
|
+
requestId,
|
|
79
|
+
error: err.message,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (msg.type === 'window:sync') {
|
|
84
|
+
if (Array.isArray(msg.windows)) {
|
|
85
|
+
windowManager.syncState({
|
|
86
|
+
version: 2,
|
|
87
|
+
windows: msg.windows,
|
|
88
|
+
tree: msg.tree ?? null,
|
|
89
|
+
focusedWindowId: typeof msg.focusedWindowId === 'string' ? msg.focusedWindowId : null,
|
|
90
|
+
fullscreenWindowId: typeof msg.fullscreenWindowId === 'string' ? msg.fullscreenWindowId : null,
|
|
91
|
+
windowIdCounter: typeof msg.windowIdCounter === 'number' ? msg.windowIdCounter : 0,
|
|
92
|
+
nextSplitDirection: msg.nextSplitDirection === 'horizontal' ||
|
|
93
|
+
msg.nextSplitDirection === 'vertical' ||
|
|
94
|
+
msg.nextSplitDirection === 'auto'
|
|
95
|
+
? msg.nextSplitDirection
|
|
96
|
+
: 'auto',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (msg.type === 'window:actions_changed') {
|
|
101
|
+
if (typeof msg.windowId === 'string' && Array.isArray(msg.actions)) {
|
|
102
|
+
windowManager.setWindowActions(msg.windowId, msg.actions);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (msg.type === 'window:action_result') {
|
|
106
|
+
if (typeof msg.requestId === 'string') {
|
|
107
|
+
const pending = pendingWindowActionRequests.get(msg.requestId);
|
|
108
|
+
if (pending) {
|
|
109
|
+
clearTimeout(pending.timeout);
|
|
110
|
+
pendingWindowActionRequests.delete(msg.requestId);
|
|
111
|
+
if (typeof msg.error === 'string' && msg.error.length > 0) {
|
|
112
|
+
pending.reject(new Error(msg.error));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
pending.resolve(msg.result);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (msg.type === 'window:ai_command_result') {
|
|
121
|
+
if (typeof msg.requestId === 'string') {
|
|
122
|
+
const pending = pendingAiCommandRequests.get(msg.requestId);
|
|
123
|
+
if (pending) {
|
|
124
|
+
clearTimeout(pending.timeout);
|
|
125
|
+
pendingAiCommandRequests.delete(msg.requestId);
|
|
126
|
+
pending.resolve({
|
|
127
|
+
ok: msg.ok === true,
|
|
128
|
+
windowId: typeof msg.windowId === 'string' ? msg.windowId : undefined,
|
|
129
|
+
error: typeof msg.error === 'string' ? msg.error : undefined,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else if (msg.type === 'ai:sessions:list') {
|
|
135
|
+
sendAiEvent({
|
|
136
|
+
type: 'sessions_sync',
|
|
137
|
+
sessionId: piSessionService.getSessionId(),
|
|
138
|
+
sessions: await piSessionService.listSessions(),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else if (msg.type === 'ai:sessions:create') {
|
|
142
|
+
if (activeAiRequestId) {
|
|
143
|
+
sendAiEvent({
|
|
144
|
+
type: 'error',
|
|
145
|
+
message: 'Cannot create a new session while the AI is responding.',
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
await piSessionService.createNewSession();
|
|
150
|
+
sendAiEvent({
|
|
151
|
+
type: 'history_sync',
|
|
152
|
+
sessionId: piSessionService.getSessionId(),
|
|
153
|
+
messages: piSessionService.getHistory(),
|
|
154
|
+
});
|
|
155
|
+
sendAiEvent({
|
|
156
|
+
type: 'sessions_sync',
|
|
157
|
+
sessionId: piSessionService.getSessionId(),
|
|
158
|
+
sessions: await piSessionService.listSessions(),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
else if (msg.type === 'ai:sessions:switch') {
|
|
162
|
+
const sessionId = typeof msg.sessionId === 'string' ? msg.sessionId : '';
|
|
163
|
+
if (activeAiRequestId) {
|
|
164
|
+
sendAiEvent({
|
|
165
|
+
type: 'error',
|
|
166
|
+
message: 'Wait for the current AI response to finish before switching sessions.',
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (!sessionId) {
|
|
171
|
+
sendAiEvent({
|
|
172
|
+
type: 'error',
|
|
173
|
+
message: 'A session ID is required to switch sessions.',
|
|
174
|
+
});
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const switched = await piSessionService.switchSession(sessionId);
|
|
178
|
+
if (!switched) {
|
|
179
|
+
sendAiEvent({
|
|
180
|
+
type: 'error',
|
|
181
|
+
message: 'The selected session could not be found.',
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
sendAiEvent({
|
|
186
|
+
type: 'history_sync',
|
|
187
|
+
sessionId: piSessionService.getSessionId(),
|
|
188
|
+
messages: piSessionService.getHistory(),
|
|
189
|
+
});
|
|
190
|
+
sendAiEvent({
|
|
191
|
+
type: 'sessions_sync',
|
|
192
|
+
sessionId: piSessionService.getSessionId(),
|
|
193
|
+
sessions: await piSessionService.listSessions(),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else if (msg.type === 'ai:sessions:rename') {
|
|
197
|
+
const title = typeof msg.title === 'string' ? msg.title.trim() : '';
|
|
198
|
+
if (activeAiRequestId) {
|
|
199
|
+
sendAiEvent({
|
|
200
|
+
type: 'error',
|
|
201
|
+
message: 'Wait for the current AI response to finish before renaming sessions.',
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (!title) {
|
|
206
|
+
sendAiEvent({
|
|
207
|
+
type: 'error',
|
|
208
|
+
message: 'A session title is required.',
|
|
209
|
+
});
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
await piSessionService.renameCurrentSession(title);
|
|
213
|
+
sendAiEvent({
|
|
214
|
+
type: 'sessions_sync',
|
|
215
|
+
sessionId: piSessionService.getSessionId(),
|
|
216
|
+
sessions: await piSessionService.listSessions(),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
else if (msg.type === 'ai:cancel') {
|
|
220
|
+
const requestId = typeof msg.requestId === 'string' ? msg.requestId : '';
|
|
221
|
+
if (!activeAiRequestId) {
|
|
222
|
+
sendAiEvent({
|
|
223
|
+
type: 'error',
|
|
224
|
+
requestId,
|
|
225
|
+
message: 'No AI request is currently running.',
|
|
226
|
+
});
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (!requestId || requestId !== activeAiRequestId) {
|
|
230
|
+
sendAiEvent({
|
|
231
|
+
type: 'error',
|
|
232
|
+
requestId,
|
|
233
|
+
message: 'Only the active AI request can be cancelled.',
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (cancelledAiRequestIds.has(requestId)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
cancelledAiRequestIds.add(requestId);
|
|
241
|
+
try {
|
|
242
|
+
await piSessionService.abort();
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
cancelledAiRequestIds.delete(requestId);
|
|
246
|
+
sendAiEvent({
|
|
247
|
+
type: 'error',
|
|
248
|
+
requestId,
|
|
249
|
+
message: err.message,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else if (msg.type === 'ai:prompt') {
|
|
254
|
+
const requestId = typeof msg.requestId === 'string' ? msg.requestId : `ai-${Date.now()}`;
|
|
255
|
+
const text = typeof msg.text === 'string' ? msg.text.trim() : '';
|
|
256
|
+
const source = msg.source === 'voice' ? 'voice' : 'text';
|
|
257
|
+
const provider = typeof msg.provider === 'string' ? msg.provider : undefined;
|
|
258
|
+
if (!text) {
|
|
259
|
+
sendAiEvent({
|
|
260
|
+
type: 'error',
|
|
261
|
+
requestId,
|
|
262
|
+
message: 'Prompt cannot be empty.',
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (activeAiRequestId) {
|
|
267
|
+
sendAiEvent({
|
|
268
|
+
type: 'error',
|
|
269
|
+
requestId,
|
|
270
|
+
message: 'Another AI request is already running. Wait for it to finish.',
|
|
271
|
+
});
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
activeAiRequestId = requestId;
|
|
275
|
+
try {
|
|
276
|
+
await piSessionService.prompt({
|
|
277
|
+
text,
|
|
278
|
+
source,
|
|
279
|
+
provider,
|
|
280
|
+
}, {
|
|
281
|
+
onEvent: (event) => sendAiEvent({
|
|
282
|
+
requestId,
|
|
283
|
+
...event,
|
|
284
|
+
}),
|
|
285
|
+
});
|
|
286
|
+
if (cancelledAiRequestIds.has(requestId)) {
|
|
287
|
+
sendAiEvent({
|
|
288
|
+
type: 'message_end',
|
|
289
|
+
requestId,
|
|
290
|
+
cancelled: true,
|
|
291
|
+
});
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
sendAiEvent({
|
|
295
|
+
type: 'history_sync',
|
|
296
|
+
sessionId: piSessionService.getSessionId(),
|
|
297
|
+
messages: piSessionService.getHistory(),
|
|
298
|
+
});
|
|
299
|
+
sendAiEvent({
|
|
300
|
+
type: 'sessions_sync',
|
|
301
|
+
sessionId: piSessionService.getSessionId(),
|
|
302
|
+
sessions: await piSessionService.listSessions(),
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
if (cancelledAiRequestIds.has(requestId)) {
|
|
307
|
+
sendAiEvent({
|
|
308
|
+
type: 'message_end',
|
|
309
|
+
requestId,
|
|
310
|
+
cancelled: true,
|
|
311
|
+
});
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
sendAiEvent({
|
|
315
|
+
type: 'error',
|
|
316
|
+
requestId,
|
|
317
|
+
message: err.message,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
finally {
|
|
321
|
+
cancelledAiRequestIds.delete(requestId);
|
|
322
|
+
if (activeAiRequestId === requestId) {
|
|
323
|
+
activeAiRequestId = null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// Ignore malformed messages
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=ws-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-routes.js","sourceRoot":"","sources":["../../src/server/ws-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA4BvE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAoB,EAAE,OAAwB;IAC3E,MAAM,EACJ,MAAM,EACN,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,wBAAwB,EACxB,oBAAoB,GACrB,GAAG,OAAO,CAAC;IAEZ,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QAClD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAE/B,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,IAAI,iBAAiB,GAAkB,IAAI,CAAC;QAC5C,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;QAEhD,SAAS,WAAW,CAAC,KAA8B;YACjD,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,UAAU;gBAChB,KAAK;aACN,CAAC,CACH,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACzB,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,mBAAmB,CAAC,CAAC,CAAC;gBAC1F,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBAE5B,MAAM,aAAa,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;oBAC5E,MAAM,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC/D,CAAC,CAAC,CAAC;gBAEH,WAAW,CAAC;oBACV,IAAI,EAAE,cAAc;oBACpB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;oBAC1C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,EAAE;iBACxC,CAAC,CAAC;gBACH,WAAW,CAAC;oBACV,IAAI,EAAE,eAAe;oBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;oBAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;iBAChD,CAAC,CAAC;gBAEH,MAAM,SAAS,GAAG,aAAa,CAAC,iBAAiB,EAAE,CAAC;gBACpD,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,IAAI,EAAE,SAAS,CAAC,IAAI;oBACpB,eAAe,EAAE,SAAS,CAAC,eAAe;oBAC1C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;oBAChD,eAAe,EAAE,SAAS,CAAC,eAAe;oBAC1C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;iBACjD,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CACV,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACzE,4DAA4D,CAC7D,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,GAAoC,EAAE,EAAE;YAClE,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEvC,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;oBAClC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;oBACpD,MAAM,UAAU,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;oBAC9C,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;wBAC3E,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,SAAS,CAAC;4BACb,IAAI,EAAE,kBAAkB;4BACxB,SAAS;4BACT,IAAI,EAAE,MAAM;yBACb,CAAC,CACH,CAAC;oBACJ,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,SAAS,CAAC;4BACb,IAAI,EAAE,kBAAkB;4BACxB,SAAS;4BACT,KAAK,EAAG,GAAa,CAAC,OAAO;yBAC9B,CAAC,CACH,CAAC;oBACJ,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBACtC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC/B,aAAa,CAAC,SAAS,CAAC;4BACtB,OAAO,EAAE,CAAC;4BACV,OAAO,EAAE,GAAG,CAAC,OAAO;4BACpB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;4BACtB,eAAe,EAAE,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;4BACrF,kBAAkB,EAChB,OAAO,GAAG,CAAC,kBAAkB,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI;4BAC5E,eAAe,EAAE,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;4BAClF,kBAAkB,EAChB,GAAG,CAAC,kBAAkB,KAAK,YAAY;gCACvC,GAAG,CAAC,kBAAkB,KAAK,UAAU;gCACrC,GAAG,CAAC,kBAAkB,KAAK,MAAM;gCAC/B,CAAC,CAAC,GAAG,CAAC,kBAAkB;gCACxB,CAAC,CAAC,MAAM;yBACb,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;oBACjD,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;wBACnE,aAAa,CAAC,gBAAgB,CAC5B,GAAG,CAAC,QAAQ,EACZ,GAAG,CAAC,OAAyC,CAC9C,CAAC;oBACJ,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;oBAC/C,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;wBACtC,MAAM,OAAO,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;wBAC/D,IAAI,OAAO,EAAE,CAAC;4BACZ,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;4BAC9B,2BAA2B,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;4BAClD,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC1D,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;4BACvC,CAAC;iCAAM,CAAC;gCACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;4BAC9B,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,0BAA0B,EAAE,CAAC;oBACnD,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;wBACtC,MAAM,OAAO,GAAG,wBAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;wBAC5D,IAAI,OAAO,EAAE,CAAC;4BACZ,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;4BAC9B,wBAAwB,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;4BAC/C,OAAO,CAAC,OAAO,CAAC;gCACd,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,IAAI;gCACnB,QAAQ,EAAE,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;gCACrE,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;6BAC7D,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;oBAC3C,WAAW,CAAC;wBACV,IAAI,EAAE,eAAe;wBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;qBAChD,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;oBAC7C,IAAI,iBAAiB,EAAE,CAAC;wBACtB,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,yDAAyD;yBACnE,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;oBAC1C,WAAW,CAAC;wBACV,IAAI,EAAE,cAAc;wBACpB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,EAAE;qBACxC,CAAC,CAAC;oBACH,WAAW,CAAC;wBACV,IAAI,EAAE,eAAe;wBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;qBAChD,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;oBAC7C,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzE,IAAI,iBAAiB,EAAE,CAAC;wBACtB,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,uEAAuE;yBACjF,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,8CAA8C;yBACxD,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;oBACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,0CAA0C;yBACpD,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,WAAW,CAAC;wBACV,IAAI,EAAE,cAAc;wBACpB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,EAAE;qBACxC,CAAC,CAAC;oBACH,WAAW,CAAC;wBACV,IAAI,EAAE,eAAe;wBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;qBAChD,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;oBAC7C,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpE,IAAI,iBAAiB,EAAE,CAAC;wBACtB,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,sEAAsE;yBAChF,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,8BAA8B;yBACxC,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,MAAM,gBAAgB,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;oBACnD,WAAW,CAAC;wBACV,IAAI,EAAE,eAAe;wBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;wBAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;qBAChD,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACpC,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;oBAEzE,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBACvB,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAE,qCAAqC;yBAC/C,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,iBAAiB,EAAE,CAAC;wBAClD,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAE,8CAA8C;yBACxD,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;wBACzC,OAAO;oBACT,CAAC;oBAED,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAErC,IAAI,CAAC;wBACH,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC;oBACjC,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,qBAAqB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;wBACxC,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAG,GAAa,CAAC,OAAO;yBAChC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACpC,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;oBACzF,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;oBACzD,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;oBAE7E,IAAI,CAAC,IAAI,EAAE,CAAC;wBACV,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAE,yBAAyB;yBACnC,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,IAAI,iBAAiB,EAAE,CAAC;wBACtB,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAE,+DAA+D;yBACzE,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,iBAAiB,GAAG,SAAS,CAAC;oBAE9B,IAAI,CAAC;wBACH,MAAM,gBAAgB,CAAC,MAAM,CAC3B;4BACE,IAAI;4BACJ,MAAM;4BACN,QAAQ;yBACT,EACD;4BACE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,WAAW,CAAC;gCACV,SAAS;gCACT,GAAG,KAAK;6BACT,CAAC;yBACL,CACF,CAAC;wBAEF,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;4BACzC,WAAW,CAAC;gCACV,IAAI,EAAE,aAAa;gCACnB,SAAS;gCACT,SAAS,EAAE,IAAI;6BAChB,CAAC,CAAC;4BACH,OAAO;wBACT,CAAC;wBAED,WAAW,CAAC;4BACV,IAAI,EAAE,cAAc;4BACpB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;4BAC1C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,EAAE;yBACxC,CAAC,CAAC;wBACH,WAAW,CAAC;4BACV,IAAI,EAAE,eAAe;4BACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE;4BAC1C,QAAQ,EAAE,MAAM,gBAAgB,CAAC,YAAY,EAAE;yBAChD,CAAC,CAAC;oBACL,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;4BACzC,WAAW,CAAC;gCACV,IAAI,EAAE,aAAa;gCACnB,SAAS;gCACT,SAAS,EAAE,IAAI;6BAChB,CAAC,CAAC;4BACH,OAAO;wBACT,CAAC;wBAED,WAAW,CAAC;4BACV,IAAI,EAAE,OAAO;4BACb,SAAS;4BACT,OAAO,EAAG,GAAa,CAAC,OAAO;yBAChC,CAAC,CAAC;oBACL,CAAC;4BAAS,CAAC;wBACT,qBAAqB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;wBACxC,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;4BACpC,iBAAiB,GAAG,IAAI,CAAC;wBAC3B,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolDefinition } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
import type { WindowManagerService } from '../window-manager.js';
|
|
3
|
+
interface ActionToolOptions {
|
|
4
|
+
windowManager: WindowManagerService;
|
|
5
|
+
invokeAction: (windowId: string, actionName: string, actionParams?: Record<string, unknown>) => Promise<unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createActionTool(options: ActionToolOptions): ToolDefinition;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=action-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-tool.d.ts","sourceRoot":"","sources":["../../../src/services/ai/action-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAoB9D,UAAU,iBAAiB;IACzB,aAAa,EAAE,oBAAoB,CAAC;IACpC,YAAY,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAiD3E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
const actionSchema = Type.Object({
|
|
3
|
+
name: Type.String({ description: 'The action name to invoke (from the Desktop Context block)' }),
|
|
4
|
+
params: Type.Optional(Type.Record(Type.String(), Type.Unknown(), {
|
|
5
|
+
description: 'JSON parameters to pass to the action handler',
|
|
6
|
+
})),
|
|
7
|
+
windowId: Type.Optional(Type.String({ description: 'Target window ID. Defaults to the focused window.' })),
|
|
8
|
+
});
|
|
9
|
+
export function createActionTool(options) {
|
|
10
|
+
const { windowManager, invokeAction } = options;
|
|
11
|
+
return {
|
|
12
|
+
name: 'action',
|
|
13
|
+
label: 'Invoke Action',
|
|
14
|
+
description: 'Invoke a MiniApp action by name with JSON parameters. Available actions and their parameter schemas are listed in the [Desktop Context] block of each user message.',
|
|
15
|
+
promptSnippet: 'Invoke a MiniApp action on a DeskTalk window. See [Desktop Context] for available actions.',
|
|
16
|
+
promptGuidelines: [
|
|
17
|
+
'Read the [Desktop Context] block in the user message to see available actions and their params.',
|
|
18
|
+
'Provide all required params as a JSON object.',
|
|
19
|
+
'If windowId is omitted, the action runs on the focused window.',
|
|
20
|
+
'Call `read_manual` with `page: "desktop/actions"` when you need the full action-invocation workflow.',
|
|
21
|
+
],
|
|
22
|
+
parameters: actionSchema,
|
|
23
|
+
async execute(_toolCallId, params) {
|
|
24
|
+
const input = params;
|
|
25
|
+
// Resolve target window — default to focused
|
|
26
|
+
const targetWindowId = input.windowId ?? windowManager.getFocusedWindow()?.id;
|
|
27
|
+
if (!targetWindowId) {
|
|
28
|
+
throw new Error('No target window: provide windowId or ensure a window is focused.');
|
|
29
|
+
}
|
|
30
|
+
// Validate that the action exists on the target window
|
|
31
|
+
const actions = windowManager.getWindowActions(targetWindowId);
|
|
32
|
+
const actionDef = actions.find((a) => a.name === input.name);
|
|
33
|
+
if (!actionDef) {
|
|
34
|
+
const available = actions.map((a) => a.name).join(', ') || 'none';
|
|
35
|
+
throw new Error(`Action "${input.name}" not found on window ${targetWindowId}. Available: ${available}`);
|
|
36
|
+
}
|
|
37
|
+
const result = await invokeAction(targetWindowId, input.name, input.params);
|
|
38
|
+
const payload = {
|
|
39
|
+
ok: true,
|
|
40
|
+
windowId: targetWindowId,
|
|
41
|
+
action: input.name,
|
|
42
|
+
result,
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }],
|
|
46
|
+
details: payload,
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=action-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-tool.js","sourceRoot":"","sources":["../../../src/services/ai/action-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4DAA4D,EAAE,CAAC;IAChG,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;QACzC,WAAW,EAAE,+CAA+C;KAC7D,CAAC,CACH;IACD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CAClF;CACF,CAAC,CAAC;AAiBH,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,qKAAqK;QACvK,aAAa,EACX,4FAA4F;QAC9F,gBAAgB,EAAE;YAChB,iGAAiG;YACjG,+CAA+C;YAC/C,gEAAgE;YAChE,sGAAsG;SACvG;QACD,UAAU,EAAE,YAAY;QACxB,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM;YAC/B,MAAM,KAAK,GAAG,MAAsB,CAAC;YAErC,6CAA6C;YAC7C,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAC,gBAAgB,EAAE,EAAE,EAAE,CAAC;YAC9E,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACvF,CAAC;YAED,uDAAuD;YACvD,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;gBAClE,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,IAAI,yBAAyB,cAAc,gBAAgB,SAAS,EAAE,CACxF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5E,MAAM,OAAO,GAAG;gBACd,EAAE,EAAE,IAAI;gBACR,QAAQ,EAAE,cAAc;gBACxB,MAAM,EAAE,KAAK,CAAC,IAAI;gBAClB,MAAM;aACP,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBACnE,OAAO,EAAE,OAAO;aACjB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolDefinition } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
import type { MiniAppManifest } from '@desktalk/sdk';
|
|
3
|
+
import type { WindowManagerService } from '../window-manager.js';
|
|
4
|
+
import type { SendAiCommand } from './window-tools.js';
|
|
5
|
+
interface AppToolOptions {
|
|
6
|
+
windowManager: WindowManagerService;
|
|
7
|
+
getMiniApps: () => MiniAppManifest[];
|
|
8
|
+
activateMiniApp: (miniAppId: string) => void;
|
|
9
|
+
deactivateMiniApp: (miniAppId: string) => void;
|
|
10
|
+
isActivated: (miniAppId: string) => boolean;
|
|
11
|
+
sendAiCommand: SendAiCommand;
|
|
12
|
+
}
|
|
13
|
+
export declare function createAppControlTool(options: AppToolOptions): ToolDefinition;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=app-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-tools.d.ts","sourceRoot":"","sources":["../../../src/services/ai/app-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAYvD,UAAU,cAAc;IACtB,aAAa,EAAE,oBAAoB,CAAC;IACpC,WAAW,EAAE,MAAM,eAAe,EAAE,CAAC;IACrC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,aAAa,EAAE,aAAa,CAAC;CAC9B;AAaD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAmI5E"}
|