@johpaz/hive-agents 0.0.37 → 0.0.39
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 +18 -18
- package/dist/hive.js +3529 -2702
- package/dist/tool-worker.js +2110 -1856
- package/dist/ui/assets/AgentCreateForm-BTCzFbca.js +1 -0
- package/dist/ui/assets/AgentDetailPage-o27TRSVw.js +1 -0
- package/dist/ui/assets/AgentNewPage-400cCpYt.js +1 -0
- package/dist/ui/{dist/assets/AgentsPage-YvSgWRiw.js → assets/AgentsPage-C-GSRk-N.js} +5 -5
- package/dist/ui/assets/ApiClientPage-BOTpz6oP.js +3 -0
- package/dist/ui/assets/{CanvasPage-DtMwGvxf.js → CanvasPage-Cvs5ctza.js} +7 -7
- package/dist/ui/assets/ChannelsPage-C5m_L7P9.js +8 -0
- package/dist/ui/{dist/assets/DashboardPage-ghl1ZguH.js → assets/DashboardPage-CztbRQdm.js} +2 -2
- package/dist/ui/assets/{LoginPage-CAmSI9Vy.js → LoginPage-OMsrx5oj.js} +1 -1
- package/dist/ui/assets/LogsPage-CcYYwjgF.js +1 -0
- package/dist/ui/{dist/assets/MeetingPage-WjjGOqqU.js → assets/MeetingPage-CrKVAfe6.js} +1 -1
- package/dist/ui/assets/{NotFound-BMeQSGcG.js → NotFound-GbAJDgoD.js} +1 -1
- package/dist/ui/assets/ProvidersPage-uqPcZUSV.js +1 -0
- package/dist/ui/{dist/assets/RecoverPage-DpW3l-yv.js → assets/RecoverPage-CwB2ByCU.js} +1 -1
- package/dist/ui/assets/SettingsPage-DKLlye0z.js +9 -0
- package/dist/ui/assets/SetupPage-DOVh1ldK.js +1 -0
- package/dist/ui/assets/WebChatPage-c-7S9jnT.js +16 -0
- package/dist/ui/assets/accordion-DAbcVQCn.js +1 -0
- package/dist/ui/{dist/assets/alert-C-NE-P3s.js → assets/alert-D_2Y3qjL.js} +1 -1
- package/dist/ui/{dist/assets/alert-dialog-C5mzbHdP.js → assets/alert-dialog-CpMxaNcu.js} +1 -1
- package/dist/ui/assets/{badge-ChpACfWO.js → badge-CxTPR6_t.js} +1 -1
- package/dist/ui/assets/bell-8BqRYmzf.js +1 -0
- package/dist/ui/assets/circle-x-Bv6WrUJo.js +1 -0
- package/dist/ui/assets/copy-dU94ZGsi.js +1 -0
- package/dist/ui/{dist/assets/dialog-QnZ0ad8O.js → assets/dialog-DfS3idb3.js} +1 -1
- package/dist/ui/{dist/assets/dropdown-menu-BK-CO3Od.js → assets/dropdown-menu-BdCbAW1z.js} +1 -1
- package/dist/ui/assets/{es-NQNoaWDx.js → es-Cz5h9_84.js} +1 -1
- package/dist/ui/assets/index-CmGm_r89.js +116 -0
- package/dist/ui/assets/index-T7HgphSn.css +2 -0
- package/dist/ui/{dist/assets/label-D2H1IR_J.js → assets/label-byJkqOYq.js} +1 -1
- package/dist/ui/assets/progress-Dtz-Mzys.js +1 -0
- package/dist/ui/assets/scroll-area-BXtLsE9E.js +1 -0
- package/dist/ui/assets/search-BGmPJ-6L.js +1 -0
- package/dist/ui/assets/select-Cl16QYa_.js +1 -0
- package/dist/ui/assets/send-BuQcUO-R.js +1 -0
- package/dist/ui/assets/shield-C-05qB-2.js +1 -0
- package/dist/ui/{dist/assets/slider-CsiUDxc3.js → assets/slider-D2I0qven.js} +1 -1
- package/dist/ui/assets/switch-h2SfQX4B.js +1 -0
- package/dist/ui/assets/table-CVkIRJKK.js +1 -0
- package/dist/ui/assets/tabs-C619jxbO.js +1 -0
- package/dist/ui/assets/textarea-wvA-FDjO.js +1 -0
- package/dist/ui/assets/useProviders-eEri6BAc.js +1 -0
- package/dist/ui/{dist/assets/vendor-radix-cw1bQaVC.js → assets/vendor-radix-D6rA7xKY.js} +4 -4
- package/dist/ui/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
- package/dist/ui/dist/assets/AgentCreateForm-BTCzFbca.js +1 -0
- package/dist/ui/dist/assets/AgentDetailPage-o27TRSVw.js +1 -0
- package/dist/ui/dist/assets/AgentNewPage-400cCpYt.js +1 -0
- package/dist/ui/{assets/AgentsPage-YvSgWRiw.js → dist/assets/AgentsPage-C-GSRk-N.js} +5 -5
- package/dist/ui/dist/assets/ApiClientPage-BOTpz6oP.js +3 -0
- package/dist/ui/dist/assets/{CanvasPage-DtMwGvxf.js → CanvasPage-Cvs5ctza.js} +7 -7
- package/dist/ui/dist/assets/ChannelsPage-C5m_L7P9.js +8 -0
- package/dist/ui/{assets/DashboardPage-ghl1ZguH.js → dist/assets/DashboardPage-CztbRQdm.js} +2 -2
- package/dist/ui/dist/assets/{LoginPage-CAmSI9Vy.js → LoginPage-OMsrx5oj.js} +1 -1
- package/dist/ui/dist/assets/LogsPage-CcYYwjgF.js +1 -0
- package/dist/ui/{assets/MeetingPage-WjjGOqqU.js → dist/assets/MeetingPage-CrKVAfe6.js} +1 -1
- package/dist/ui/dist/assets/{NotFound-BMeQSGcG.js → NotFound-GbAJDgoD.js} +1 -1
- package/dist/ui/dist/assets/ProvidersPage-uqPcZUSV.js +1 -0
- package/dist/ui/{assets/RecoverPage-DpW3l-yv.js → dist/assets/RecoverPage-CwB2ByCU.js} +1 -1
- package/dist/ui/dist/assets/SettingsPage-DKLlye0z.js +9 -0
- package/dist/ui/dist/assets/SetupPage-DOVh1ldK.js +1 -0
- package/dist/ui/dist/assets/WebChatPage-c-7S9jnT.js +16 -0
- package/dist/ui/dist/assets/accordion-DAbcVQCn.js +1 -0
- package/dist/ui/{assets/alert-C-NE-P3s.js → dist/assets/alert-D_2Y3qjL.js} +1 -1
- package/dist/ui/{assets/alert-dialog-C5mzbHdP.js → dist/assets/alert-dialog-CpMxaNcu.js} +1 -1
- package/dist/ui/dist/assets/{badge-ChpACfWO.js → badge-CxTPR6_t.js} +1 -1
- package/dist/ui/dist/assets/bell-8BqRYmzf.js +1 -0
- package/dist/ui/dist/assets/circle-x-Bv6WrUJo.js +1 -0
- package/dist/ui/dist/assets/copy-dU94ZGsi.js +1 -0
- package/dist/ui/{assets/dialog-QnZ0ad8O.js → dist/assets/dialog-DfS3idb3.js} +1 -1
- package/dist/ui/{assets/dropdown-menu-BK-CO3Od.js → dist/assets/dropdown-menu-BdCbAW1z.js} +1 -1
- package/dist/ui/dist/assets/{es-NQNoaWDx.js → es-Cz5h9_84.js} +1 -1
- package/dist/ui/dist/assets/index-CmGm_r89.js +116 -0
- package/dist/ui/dist/assets/index-T7HgphSn.css +2 -0
- package/dist/ui/{assets/label-D2H1IR_J.js → dist/assets/label-byJkqOYq.js} +1 -1
- package/dist/ui/dist/assets/progress-Dtz-Mzys.js +1 -0
- package/dist/ui/dist/assets/scroll-area-BXtLsE9E.js +1 -0
- package/dist/ui/dist/assets/search-BGmPJ-6L.js +1 -0
- package/dist/ui/dist/assets/select-Cl16QYa_.js +1 -0
- package/dist/ui/dist/assets/send-BuQcUO-R.js +1 -0
- package/dist/ui/dist/assets/shield-C-05qB-2.js +1 -0
- package/dist/ui/{assets/slider-CsiUDxc3.js → dist/assets/slider-D2I0qven.js} +1 -1
- package/dist/ui/dist/assets/switch-h2SfQX4B.js +1 -0
- package/dist/ui/dist/assets/table-CVkIRJKK.js +1 -0
- package/dist/ui/dist/assets/tabs-C619jxbO.js +1 -0
- package/dist/ui/dist/assets/textarea-wvA-FDjO.js +1 -0
- package/dist/ui/dist/assets/useProviders-eEri6BAc.js +1 -0
- package/dist/ui/{assets/vendor-radix-cw1bQaVC.js → dist/assets/vendor-radix-D6rA7xKY.js} +4 -4
- package/dist/ui/dist/assets/{vendor-react-D4s9E-zj.js → vendor-react-BU5iQU4f.js} +1 -1
- package/dist/ui/dist/index.html +6 -6
- package/dist/ui/index.html +6 -6
- package/package.json +1 -1
- package/packages/cli/src/adapters/binary.ts +8 -4
- package/packages/cli/src/adapters/bun-global.ts +5 -1
- package/packages/cli/src/adapters/config.ts +4 -3
- package/packages/cli/src/adapters/docker.ts +2 -1
- package/packages/cli/src/commands/gateway.ts +123 -9
- package/packages/cli/src/commands/logs.ts +2 -1
- package/packages/cli/src/commands/onboard.ts +1 -1
- package/packages/cli/src/commands/sessions.ts +2 -1
- package/packages/cli/src/commands/skills.ts +2 -1
- package/packages/core/src/agent/agent-loop.ts +4 -14
- package/packages/core/src/agent/context-compiler.ts +1 -1
- package/packages/core/src/agent/conversation-store.ts +4 -5
- package/packages/core/src/agent/llm-client.ts +4 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +23 -8
- package/packages/core/src/agent/llm-providers/interface.ts +5 -1
- package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
- package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
- package/packages/core/src/agent/providers/index.ts +3 -4
- package/packages/core/src/agent/tool-selector.ts +3 -4
- package/packages/core/src/channels/whatsapp.ts +13 -1
- package/packages/core/src/config/loader.ts +7 -7
- package/packages/core/src/gateway/helpers/path.ts +2 -1
- package/packages/core/src/gateway/initializer.ts +4 -4
- package/packages/core/src/gateway/llm-local/downloader.ts +130 -11
- package/packages/core/src/gateway/llm-local/index.ts +2 -0
- package/packages/core/src/gateway/llm-local/models.ts +4 -3
- package/packages/core/src/gateway/resolver.ts +5 -1
- package/packages/core/src/gateway/router.ts +7 -5
- package/packages/core/src/gateway/routes/chat.ts +16 -16
- package/packages/core/src/gateway/routes/http-client.ts +16 -0
- package/packages/core/src/gateway/routes/llm-local.ts +51 -5
- package/packages/core/src/gateway/routes/providers.ts +43 -2
- package/packages/core/src/gateway/server.ts +55 -47
- package/packages/core/src/gateway/tts/src/install.ts +17 -9
- package/packages/core/src/storage/crypto.ts +152 -20
- package/packages/core/src/storage/migrate.ts +51 -18
- package/packages/core/src/storage/seed.ts +77 -35
- package/packages/core/src/tool-runtime/index.ts +42 -1
- package/packages/core/src/tools/api/api-request.ts +174 -0
- package/packages/core/src/tools/api/index.ts +16 -0
- package/packages/core/src/tools/index.ts +12 -0
- package/packages/core/src/tools/web/browser-click.ts +2 -2
- package/packages/core/src/tools/web/browser-extract.ts +22 -6
- package/packages/core/src/tools/web/browser-navigate.ts +34 -18
- package/packages/core/src/tools/web/browser-screenshot.ts +40 -8
- package/packages/core/src/tools/web/browser-script.ts +2 -2
- package/packages/core/src/tools/web/browser-service.ts +295 -341
- package/packages/core/src/tools/web/browser-type.ts +5 -10
- package/packages/core/src/tools/web/browser-wait.ts +2 -2
- package/packages/core/src/tools/web/index.ts +1 -1
- package/packages/core/src/utils/logger.ts +2 -1
- package/packages/mcp/src/manager.ts +2 -1
- package/packages/skills/src/bundled/api/api_client/SKILL.md +132 -0
- package/packages/skills/src/bundled-data.generated.ts +1274 -1217
- package/packages/skills/src/loader.ts +2 -1
- package/dist/ui/assets/AgentCreateForm-tJZv9FZC.js +0 -1
- package/dist/ui/assets/AgentDetailPage-Du-mRcAX.js +0 -1
- package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +0 -1
- package/dist/ui/assets/ChannelsPage-BdBXWHjj.js +0 -8
- package/dist/ui/assets/LogsPage-DAPBHkwK.js +0 -1
- package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +0 -1
- package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +0 -9
- package/dist/ui/assets/SetupPage-DKmLVUaj.js +0 -1
- package/dist/ui/assets/WebChatPage-CVRcKept.js +0 -16
- package/dist/ui/assets/accordion-C5d5Rm5z.js +0 -1
- package/dist/ui/assets/globe-DeCQTCDJ.js +0 -1
- package/dist/ui/assets/index-B2fCYtTS.css +0 -2
- package/dist/ui/assets/index-DMCjjdqf.js +0 -116
- package/dist/ui/assets/progress-BherYzY6.js +0 -1
- package/dist/ui/assets/scroll-area-DkeyX32e.js +0 -1
- package/dist/ui/assets/send-B0H5SEIE.js +0 -1
- package/dist/ui/assets/switch-BDwN8RYV.js +0 -1
- package/dist/ui/assets/table-CSc8ubon.js +0 -1
- package/dist/ui/assets/textarea-CXgXWKrT.js +0 -1
- package/dist/ui/assets/useProviders-C6_QHsEi.js +0 -1
- package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +0 -1
- package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +0 -1
- package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +0 -1
- package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +0 -8
- package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +0 -1
- package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +0 -1
- package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +0 -9
- package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +0 -1
- package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +0 -16
- package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +0 -1
- package/dist/ui/dist/assets/globe-DeCQTCDJ.js +0 -1
- package/dist/ui/dist/assets/index-B2fCYtTS.css +0 -2
- package/dist/ui/dist/assets/index-DMCjjdqf.js +0 -116
- package/dist/ui/dist/assets/progress-BherYzY6.js +0 -1
- package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +0 -1
- package/dist/ui/dist/assets/send-B0H5SEIE.js +0 -1
- package/dist/ui/dist/assets/switch-BDwN8RYV.js +0 -1
- package/dist/ui/dist/assets/table-CSc8ubon.js +0 -1
- package/dist/ui/dist/assets/textarea-CXgXWKrT.js +0 -1
- package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +0 -1
- /package/dist/ui/assets/{card-CNf6BS2e.js → card-CXAm46at.js} +0 -0
- /package/dist/ui/assets/{cpu-Cdgc_B1K.js → cpu-DSpPVLAz.js} +0 -0
- /package/dist/ui/assets/{download-C3ifGMjJ.js → download-D9ZyUZZR.js} +0 -0
- /package/dist/ui/assets/{external-link-BvxYeTP1.js → external-link-CHPbUorN.js} +0 -0
- /package/dist/ui/assets/{eye-DqNTU_GD.js → eye-epHJZ_nQ.js} +0 -0
- /package/dist/ui/assets/{file-text-BT_9S9SM.js → file-text-BEjEmgby.js} +0 -0
- /package/dist/ui/assets/{folder-open-BhH8y9ac.js → folder-open-iQMHVEqS.js} +0 -0
- /package/dist/ui/assets/{format-GVHeOyWI.js → format-oFACFaca.js} +0 -0
- /package/dist/ui/assets/{gateway-url-COCbW0IR.js → gateway-url-iG-C6Agn.js} +0 -0
- /package/dist/ui/assets/{gauge-D_TMa4i9.js → gauge-D0_GMEcq.js} +0 -0
- /package/dist/ui/assets/{settings-Ds4SqD8s.js → settings-CcMGI1iU.js} +0 -0
- /package/dist/ui/assets/{sparkles-yUEb-7oH.js → sparkles-D6fx8JC5.js} +0 -0
- /package/dist/ui/assets/{trash-2-CNjMkoq6.js → trash-2-BHRa5ft9.js} +0 -0
- /package/dist/ui/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-D4nwAVbc.js} +0 -0
- /package/dist/ui/assets/{vendor-router-C9pIYwbJ.js → vendor-router-pCP7sjma.js} +0 -0
- /package/dist/ui/assets/{volume-2-CeSXNDv4.js → volume-2-B6tkRy2u.js} +0 -0
- /package/dist/ui/assets/{zap-hlXjpSeA.js → zap-QO7iWMRg.js} +0 -0
- /package/dist/ui/dist/assets/{card-CNf6BS2e.js → card-CXAm46at.js} +0 -0
- /package/dist/ui/dist/assets/{cpu-Cdgc_B1K.js → cpu-DSpPVLAz.js} +0 -0
- /package/dist/ui/dist/assets/{download-C3ifGMjJ.js → download-D9ZyUZZR.js} +0 -0
- /package/dist/ui/dist/assets/{external-link-BvxYeTP1.js → external-link-CHPbUorN.js} +0 -0
- /package/dist/ui/dist/assets/{eye-DqNTU_GD.js → eye-epHJZ_nQ.js} +0 -0
- /package/dist/ui/dist/assets/{file-text-BT_9S9SM.js → file-text-BEjEmgby.js} +0 -0
- /package/dist/ui/dist/assets/{folder-open-BhH8y9ac.js → folder-open-iQMHVEqS.js} +0 -0
- /package/dist/ui/dist/assets/{format-GVHeOyWI.js → format-oFACFaca.js} +0 -0
- /package/dist/ui/dist/assets/{gateway-url-COCbW0IR.js → gateway-url-iG-C6Agn.js} +0 -0
- /package/dist/ui/dist/assets/{gauge-D_TMa4i9.js → gauge-D0_GMEcq.js} +0 -0
- /package/dist/ui/dist/assets/{settings-Ds4SqD8s.js → settings-CcMGI1iU.js} +0 -0
- /package/dist/ui/dist/assets/{sparkles-yUEb-7oH.js → sparkles-D6fx8JC5.js} +0 -0
- /package/dist/ui/dist/assets/{trash-2-CNjMkoq6.js → trash-2-BHRa5ft9.js} +0 -0
- /package/dist/ui/dist/assets/{triangle-alert-C9Y8Ub4X.js → triangle-alert-D4nwAVbc.js} +0 -0
- /package/dist/ui/dist/assets/{vendor-router-C9pIYwbJ.js → vendor-router-pCP7sjma.js} +0 -0
- /package/dist/ui/dist/assets/{volume-2-CeSXNDv4.js → volume-2-B6tkRy2u.js} +0 -0
- /package/dist/ui/dist/assets/{zap-hlXjpSeA.js → zap-QO7iWMRg.js} +0 -0
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
loadProviderApiKey, storeProviderApiKey,
|
|
5
5
|
loadProviderHeaders, storeProviderHeaders,
|
|
6
6
|
} from "../../storage/crypto"
|
|
7
|
+
import { listLocalModels } from "../llm-local/downloader"
|
|
7
8
|
|
|
8
9
|
export async function handleGetProviders(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
9
10
|
const rawProviders = getDb().query(`
|
|
@@ -24,20 +25,60 @@ export async function handleGetProviders(req: Request, addCorsHeaders: (r: Respo
|
|
|
24
25
|
})
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
// Inyectar modelos locales descargados dinámicamente para local-llama
|
|
29
|
+
try {
|
|
30
|
+
const localModels = listLocalModels()
|
|
31
|
+
const downloadedLocalModels = localModels.filter(m => m.downloaded)
|
|
32
|
+
if (downloadedLocalModels.length > 0) {
|
|
33
|
+
const existingLocalModels = modelsByProvider["local-llama"] || []
|
|
34
|
+
for (const localModel of downloadedLocalModels) {
|
|
35
|
+
const existingIdx = existingLocalModels.findIndex((m: any) => m.id === localModel.id)
|
|
36
|
+
if (existingIdx === -1) {
|
|
37
|
+
existingLocalModels.push({
|
|
38
|
+
id: localModel.id,
|
|
39
|
+
name: localModel.name,
|
|
40
|
+
provider_id: "local-llama",
|
|
41
|
+
model_type: "llm",
|
|
42
|
+
context_window: 16000,
|
|
43
|
+
capabilities: JSON.stringify(["chat", "local"]),
|
|
44
|
+
enabled: true,
|
|
45
|
+
active: true,
|
|
46
|
+
})
|
|
47
|
+
} else {
|
|
48
|
+
// Modelo del seed ya existe pero está descargado: forzar activo
|
|
49
|
+
existingLocalModels[existingIdx] = {
|
|
50
|
+
...existingLocalModels[existingIdx],
|
|
51
|
+
enabled: true,
|
|
52
|
+
active: true,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
modelsByProvider["local-llama"] = existingLocalModels
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
// Ignorar si no se pueden obtener modelos locales
|
|
60
|
+
}
|
|
61
|
+
|
|
27
62
|
const providers = await Promise.all(rawProviders.map(async (p) => {
|
|
28
63
|
const apiKey = await loadProviderApiKey(p.id as string)
|
|
29
64
|
const headers = await loadProviderHeaders(p.id as string)
|
|
65
|
+
const providerModels = modelsByProvider[p.id as string] || []
|
|
66
|
+
// Auto-activar local-llama si tiene modelos descargados dinámicamente
|
|
67
|
+
let active = p.active
|
|
68
|
+
if (p.id === "local-llama" && providerModels.some((m: any) => m.active || m.enabled)) {
|
|
69
|
+
active = true
|
|
70
|
+
}
|
|
30
71
|
return {
|
|
31
72
|
id: p.id,
|
|
32
73
|
name: p.name,
|
|
33
74
|
base_url: p.base_url,
|
|
34
75
|
enabled: p.enabled,
|
|
35
|
-
active
|
|
76
|
+
active,
|
|
36
77
|
num_ctx: p.num_ctx ?? null,
|
|
37
78
|
has_api_key: apiKey ? 1 : 0,
|
|
38
79
|
has_headers: Object.keys(headers).length > 0 ? 1 : 0,
|
|
39
80
|
masked_api_key: apiKey ? maskApiKey(apiKey) : null,
|
|
40
|
-
models:
|
|
81
|
+
models: providerModels,
|
|
41
82
|
}
|
|
42
83
|
}))
|
|
43
84
|
|
|
@@ -73,12 +73,13 @@ import { handleGetModels, handleCreateModel, handleToggleModel, handleGetModelsC
|
|
|
73
73
|
import { handleGetVoiceProviders, handleGetConfiguredVoiceProviders, handleSaveVoiceProviderKey, handleTestVoice, handleGetChannelVoice, handleUpdateChannelVoice, handleGetVoiceProviderVoices } from "./routes/voice";
|
|
74
74
|
import { handleGetVisionProviders, handleGetChannelVision, handleUpdateChannelVision, handleOcrImage } from "./routes/multimodal";
|
|
75
75
|
import { handleGetLocalTTSStatus, handleGetLocalTTSLogs, handleInstallLocalTTS, handleStartLocalTTS, handleStopLocalTTS, handleSpeakLocalTTS, handleGetAvailableModels, handleGetInstalledVoices, handleDownloadModel, handleGetDownloadLogs, initializeLocalTTS } from "./routes/tts-local";
|
|
76
|
-
import { handleGetLocalLLMStatus, handleGetLocalLLMLogs, handleInstallLocalLLM, handleStartLocalLLM, handleStopLocalLLM, handleDownloadLLMModel, initializeLocalLLM } from "./routes/llm-local";
|
|
76
|
+
import { handleGetLocalLLMStatus, handleGetLocalLLMLogs, handleInstallLocalLLM, handleStartLocalLLM, handleStopLocalLLM, handleDownloadLLMModel, handleGetDownloadProgress, initializeLocalLLM } from "./routes/llm-local";
|
|
77
77
|
import { handleCreateMeeting, handleListMeetings, handleGetMeeting, handleAddMeetingSegment, handleStopMeeting } from "./routes/meeting";
|
|
78
78
|
import { handleGetActivityStats, handleGetSystemStats, handleGetUsageStats, handleSystemReload, handleApiReload, handleGetVersion, handleTriggerUpdate } from "./routes/system";
|
|
79
79
|
import { handleGetChatHistory, handleGetCanvas, handleGetNotes, handleUpdateNote } from "./routes/chat";
|
|
80
80
|
import { handleChat as handlePostChat } from "./routes/chat";
|
|
81
81
|
import { handleGetConfig } from "./routes/config";
|
|
82
|
+
import { handleHttpRequest } from "./routes/http-client";
|
|
82
83
|
import { handleGetWorkspace, handleUpdateWorkspace, handleValidateWorkspace, handleCreateWorkspace, handleOpenWorkspace } from "./routes/workspace";
|
|
83
84
|
import { getNarration, expandPath, addCorsHeaders, CORS_ORIGINS } from "./helpers";
|
|
84
85
|
import { redactConfig } from "./helpers";
|
|
@@ -373,7 +374,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
373
374
|
|
|
374
375
|
log.info(` Content: ${messageContent.substring(0, 150)}${messageContent.length > 150 ? "..." : ""}`);
|
|
375
376
|
|
|
376
|
-
const { userId } = resolveContext({
|
|
377
|
+
const { userId, threadId: conversationThreadId } = resolveContext({
|
|
377
378
|
channel: message.channel,
|
|
378
379
|
channelUserId: message.sessionId,
|
|
379
380
|
});
|
|
@@ -385,8 +386,8 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
385
386
|
channelManager.startTyping(message.channel, message.sessionId),
|
|
386
387
|
]);
|
|
387
388
|
|
|
388
|
-
//
|
|
389
|
-
const unifiedSessionId =
|
|
389
|
+
// conversationThreadId = conversations.thread_id canónico compartido por todos los canales
|
|
390
|
+
const unifiedSessionId = conversationThreadId;
|
|
390
391
|
// routingSessionId = peerId del canal → para enviar respuestas de vuelta al canal correcto
|
|
391
392
|
const routingSessionId = message.sessionId;
|
|
392
393
|
|
|
@@ -961,6 +962,11 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
961
962
|
}
|
|
962
963
|
}
|
|
963
964
|
|
|
965
|
+
// ── HTTP Client API ────────────────────────────────────────────────
|
|
966
|
+
if ((url.pathname === "/api/http-request" || url.pathname === "/api/http-request/") && req.method === "POST") {
|
|
967
|
+
return await handleHttpRequest(req, addCorsHeaders)
|
|
968
|
+
}
|
|
969
|
+
|
|
964
970
|
// ── Tasks API ─────────────────────────────────────────────────────
|
|
965
971
|
if ((url.pathname === "/api/tasks" || url.pathname === "/api/tasks/") && req.method === "GET") {
|
|
966
972
|
return await handleGetTasks(req, addCorsHeaders)
|
|
@@ -1626,6 +1632,9 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
1626
1632
|
if (url.pathname === "/api/llm-local/download-model" && req.method === "POST") {
|
|
1627
1633
|
return await handleDownloadLLMModel(req, addCorsHeaders)
|
|
1628
1634
|
}
|
|
1635
|
+
if (url.pathname === "/api/llm-local/download-progress" && req.method === "GET") {
|
|
1636
|
+
return await handleGetDownloadProgress(req, addCorsHeaders)
|
|
1637
|
+
}
|
|
1629
1638
|
|
|
1630
1639
|
// ── Meeting Transcription API ────────────────────────────────────────
|
|
1631
1640
|
if (url.pathname === "/api/meetings" && req.method === "POST") {
|
|
@@ -1940,7 +1949,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
1940
1949
|
return;
|
|
1941
1950
|
}
|
|
1942
1951
|
try {
|
|
1943
|
-
const { userId } = resolveContext({ channel: "webchat", channelUserId: sessionId });
|
|
1952
|
+
const { userId, threadId: conversationThreadId } = resolveContext({ channel: "webchat", channelUserId: sessionId });
|
|
1944
1953
|
const messages = [{ role: "user" as const, content: interactionMsg }];
|
|
1945
1954
|
let streamedContent = "";
|
|
1946
1955
|
const messageId = crypto.randomUUID();
|
|
@@ -1949,9 +1958,9 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
1949
1958
|
provider: dbProvider as any,
|
|
1950
1959
|
messages,
|
|
1951
1960
|
maxTokens: 4096,
|
|
1952
|
-
tools: prepareTools(agent,
|
|
1961
|
+
tools: prepareTools(agent, conversationThreadId),
|
|
1953
1962
|
maxSteps: 15,
|
|
1954
|
-
threadId:
|
|
1963
|
+
threadId: conversationThreadId,
|
|
1955
1964
|
userId,
|
|
1956
1965
|
onToken: async (token: string) => {
|
|
1957
1966
|
if (signal.aborted) return;
|
|
@@ -2015,7 +2024,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2015
2024
|
return;
|
|
2016
2025
|
}
|
|
2017
2026
|
try {
|
|
2018
|
-
const { userId } = resolveContext({ channel: "webchat", channelUserId: sessionId });
|
|
2027
|
+
const { userId, threadId: conversationThreadId } = resolveContext({ channel: "webchat", channelUserId: sessionId });
|
|
2019
2028
|
const messages = [{ role: "user" as const, content: interactionMsg }];
|
|
2020
2029
|
let streamedContent = "";
|
|
2021
2030
|
const messageId = crypto.randomUUID();
|
|
@@ -2024,9 +2033,9 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2024
2033
|
provider: dbProvider as any,
|
|
2025
2034
|
messages,
|
|
2026
2035
|
maxTokens: 4096,
|
|
2027
|
-
tools: prepareTools(agent,
|
|
2036
|
+
tools: prepareTools(agent, conversationThreadId),
|
|
2028
2037
|
maxSteps: 15,
|
|
2029
|
-
threadId:
|
|
2038
|
+
threadId: conversationThreadId,
|
|
2030
2039
|
userId,
|
|
2031
2040
|
onToken: async (token: string) => {
|
|
2032
2041
|
if (signal.aborted) return;
|
|
@@ -2157,14 +2166,14 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2157
2166
|
}
|
|
2158
2167
|
|
|
2159
2168
|
try {
|
|
2160
|
-
const
|
|
2161
|
-
const messages = [{ role: "user" as const, content: messageContent }];
|
|
2162
|
-
log.info(`Generating response for session ${unifiedSessionId}...`);
|
|
2163
|
-
|
|
2164
|
-
const { userId } = resolveContext({
|
|
2169
|
+
const { userId, threadId: conversationThreadId } = resolveContext({
|
|
2165
2170
|
channel: "webchat",
|
|
2166
2171
|
channelUserId: msg.sessionId,
|
|
2167
2172
|
});
|
|
2173
|
+
const unifiedSessionId = conversationThreadId;
|
|
2174
|
+
const routingSessionId = msg.sessionId;
|
|
2175
|
+
const messages = [{ role: "user" as const, content: messageContent }];
|
|
2176
|
+
log.info(`Generating response for session ${unifiedSessionId}...`);
|
|
2168
2177
|
|
|
2169
2178
|
// Streaming: send tokens as they arrive
|
|
2170
2179
|
let streamedContent = "";
|
|
@@ -2185,7 +2194,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2185
2194
|
ws.send(JSON.stringify({
|
|
2186
2195
|
type: "message",
|
|
2187
2196
|
id: messageId,
|
|
2188
|
-
sessionId:
|
|
2197
|
+
sessionId: routingSessionId,
|
|
2189
2198
|
content: token,
|
|
2190
2199
|
isChunk: true,
|
|
2191
2200
|
isStep: false,
|
|
@@ -2200,7 +2209,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2200
2209
|
if (trimmedMessage) {
|
|
2201
2210
|
ws.send(JSON.stringify({
|
|
2202
2211
|
type: "progress",
|
|
2203
|
-
sessionId:
|
|
2212
|
+
sessionId: routingSessionId,
|
|
2204
2213
|
content: trimmedMessage,
|
|
2205
2214
|
} as OutboundMessage));
|
|
2206
2215
|
}
|
|
@@ -2212,7 +2221,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2212
2221
|
const narration = getNarration(step.toolName);
|
|
2213
2222
|
ws.send(JSON.stringify({
|
|
2214
2223
|
type: "progress",
|
|
2215
|
-
sessionId:
|
|
2224
|
+
sessionId: routingSessionId,
|
|
2216
2225
|
content: narration,
|
|
2217
2226
|
} as OutboundMessage));
|
|
2218
2227
|
return;
|
|
@@ -2227,7 +2236,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2227
2236
|
if (userMessage) {
|
|
2228
2237
|
ws.send(JSON.stringify({
|
|
2229
2238
|
type: "progress",
|
|
2230
|
-
sessionId:
|
|
2239
|
+
sessionId: routingSessionId,
|
|
2231
2240
|
content: userMessage,
|
|
2232
2241
|
} as OutboundMessage));
|
|
2233
2242
|
}
|
|
@@ -2248,7 +2257,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2248
2257
|
let ttsProviderUsed: string | null = null;
|
|
2249
2258
|
let ttsMimeType: string | null = null;
|
|
2250
2259
|
|
|
2251
|
-
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId:
|
|
2260
|
+
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId: routingSessionId } as OutboundMessage));
|
|
2252
2261
|
|
|
2253
2262
|
// Don't send text message if already streamed (content came via onToken)
|
|
2254
2263
|
const alreadyStreamed = streamedContent.length > 0;
|
|
@@ -2258,7 +2267,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2258
2267
|
if (!voiceCfg.ttsProvider) {
|
|
2259
2268
|
ws.send(JSON.stringify({
|
|
2260
2269
|
type: "message",
|
|
2261
|
-
sessionId:
|
|
2270
|
+
sessionId: routingSessionId,
|
|
2262
2271
|
content: `${content}\n\n🔊 Para recibir respuestas en audio, configura el proveedor TTS en Configuración > Canales > WebChat (ej: elevenlabs)`,
|
|
2263
2272
|
isStep: false,
|
|
2264
2273
|
} as OutboundMessage));
|
|
@@ -2273,7 +2282,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2273
2282
|
log.info(`Audio generated: ${base64Audio.length} bytes, mimeType: ${audioOutput.mimeType}`);
|
|
2274
2283
|
ws.send(JSON.stringify({
|
|
2275
2284
|
type: "message",
|
|
2276
|
-
sessionId:
|
|
2285
|
+
sessionId: routingSessionId,
|
|
2277
2286
|
content,
|
|
2278
2287
|
audio: base64Audio,
|
|
2279
2288
|
mimeType: audioOutput.mimeType,
|
|
@@ -2281,11 +2290,11 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2281
2290
|
} as OutboundMessage));
|
|
2282
2291
|
} catch (ttsError) {
|
|
2283
2292
|
log.error(`TTS failed: ${(ttsError as Error).message}), sending text instead`);
|
|
2284
|
-
ws.send(JSON.stringify({ type: "message", sessionId:
|
|
2293
|
+
ws.send(JSON.stringify({ type: "message", sessionId: routingSessionId, content, isStep: false } as OutboundMessage));
|
|
2285
2294
|
}
|
|
2286
2295
|
}
|
|
2287
2296
|
} else {
|
|
2288
|
-
ws.send(JSON.stringify({ type: "message", sessionId:
|
|
2297
|
+
ws.send(JSON.stringify({ type: "message", sessionId: routingSessionId, content, isStep: false } as OutboundMessage));
|
|
2289
2298
|
}
|
|
2290
2299
|
} else if (alreadyStreamed && shouldSpeak && voiceCfg.ttsProvider) {
|
|
2291
2300
|
try {
|
|
@@ -2295,7 +2304,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2295
2304
|
log.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
2296
2305
|
ws.send(JSON.stringify({
|
|
2297
2306
|
type: "message",
|
|
2298
|
-
sessionId:
|
|
2307
|
+
sessionId: routingSessionId,
|
|
2299
2308
|
content,
|
|
2300
2309
|
audio: base64Audio,
|
|
2301
2310
|
mimeType: audioOutput.mimeType,
|
|
@@ -2349,7 +2358,12 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2349
2358
|
}
|
|
2350
2359
|
|
|
2351
2360
|
try {
|
|
2352
|
-
const
|
|
2361
|
+
const { userId, threadId: conversationThreadId } = resolveContext({
|
|
2362
|
+
channel: "webchat",
|
|
2363
|
+
channelUserId: msg.sessionId,
|
|
2364
|
+
});
|
|
2365
|
+
const unifiedSessionId = conversationThreadId;
|
|
2366
|
+
const routingSessionId = msg.sessionId;
|
|
2353
2367
|
|
|
2354
2368
|
// Multimodal: process image/document if present
|
|
2355
2369
|
let finalMessageContent = msg.content;
|
|
@@ -2418,11 +2432,6 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2418
2432
|
|
|
2419
2433
|
log.info(`Generating response for session ${unifiedSessionId} (multimodal: ${!!(msg.image || msg.document)})...`);
|
|
2420
2434
|
|
|
2421
|
-
const { userId } = resolveContext({
|
|
2422
|
-
channel: "webchat",
|
|
2423
|
-
channelUserId: msg.sessionId,
|
|
2424
|
-
});
|
|
2425
|
-
|
|
2426
2435
|
// Streaming: send tokens as they arrive
|
|
2427
2436
|
let streamedContent = "";
|
|
2428
2437
|
let messageId = crypto.randomUUID();
|
|
@@ -2443,7 +2452,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2443
2452
|
ws.send(JSON.stringify({
|
|
2444
2453
|
type: "message",
|
|
2445
2454
|
id: messageId,
|
|
2446
|
-
sessionId:
|
|
2455
|
+
sessionId: routingSessionId,
|
|
2447
2456
|
content: token,
|
|
2448
2457
|
isChunk: true,
|
|
2449
2458
|
isStep: false,
|
|
@@ -2458,7 +2467,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2458
2467
|
if (trimmedMessage) {
|
|
2459
2468
|
ws.send(JSON.stringify({
|
|
2460
2469
|
type: "progress",
|
|
2461
|
-
sessionId:
|
|
2470
|
+
sessionId: routingSessionId,
|
|
2462
2471
|
content: trimmedMessage,
|
|
2463
2472
|
} as OutboundMessage));
|
|
2464
2473
|
}
|
|
@@ -2470,7 +2479,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2470
2479
|
const narration = getNarration(step.toolName);
|
|
2471
2480
|
ws.send(JSON.stringify({
|
|
2472
2481
|
type: "progress",
|
|
2473
|
-
sessionId:
|
|
2482
|
+
sessionId: routingSessionId,
|
|
2474
2483
|
content: narration,
|
|
2475
2484
|
} as OutboundMessage));
|
|
2476
2485
|
return;
|
|
@@ -2485,7 +2494,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2485
2494
|
if (userMessage) {
|
|
2486
2495
|
ws.send(JSON.stringify({
|
|
2487
2496
|
type: "progress",
|
|
2488
|
-
sessionId:
|
|
2497
|
+
sessionId: routingSessionId,
|
|
2489
2498
|
content: userMessage,
|
|
2490
2499
|
} as OutboundMessage));
|
|
2491
2500
|
}
|
|
@@ -2506,7 +2515,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2506
2515
|
let ttsProviderUsed: string | null = null;
|
|
2507
2516
|
let ttsMimeType: string | null = null;
|
|
2508
2517
|
|
|
2509
|
-
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId:
|
|
2518
|
+
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId: routingSessionId } as OutboundMessage));
|
|
2510
2519
|
|
|
2511
2520
|
// Don't send text message if already streamed (content came via onToken)
|
|
2512
2521
|
const alreadyStreamed = streamedContent.length > 0;
|
|
@@ -2516,7 +2525,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2516
2525
|
if (!voiceConfig.ttsProvider) {
|
|
2517
2526
|
ws.send(JSON.stringify({
|
|
2518
2527
|
type: "message",
|
|
2519
|
-
sessionId:
|
|
2528
|
+
sessionId: routingSessionId,
|
|
2520
2529
|
content: `${content}\n\n🔊 Para recibir respuestas en audio, configura el proveedor TTS en Configuración > Canales > WebChat (ej: elevenlabs)`,
|
|
2521
2530
|
isStep: false
|
|
2522
2531
|
} as OutboundMessage));
|
|
@@ -2530,7 +2539,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2530
2539
|
const base64Audio = (audioOutput.data as Buffer).toString("base64");
|
|
2531
2540
|
ws.send(JSON.stringify({
|
|
2532
2541
|
type: "message",
|
|
2533
|
-
sessionId:
|
|
2542
|
+
sessionId: routingSessionId,
|
|
2534
2543
|
content,
|
|
2535
2544
|
audio: base64Audio,
|
|
2536
2545
|
mimeType: audioOutput.mimeType,
|
|
@@ -2538,11 +2547,11 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2538
2547
|
} as OutboundMessage));
|
|
2539
2548
|
} catch (ttsError) {
|
|
2540
2549
|
log.error(`TTS failed: ${(ttsError as Error).message}), sending text instead`);
|
|
2541
|
-
ws.send(JSON.stringify({ type: "message", sessionId:
|
|
2550
|
+
ws.send(JSON.stringify({ type: "message", sessionId: routingSessionId, content, isStep: false } as OutboundMessage));
|
|
2542
2551
|
}
|
|
2543
2552
|
}
|
|
2544
2553
|
} else {
|
|
2545
|
-
ws.send(JSON.stringify({ type: "message", sessionId:
|
|
2554
|
+
ws.send(JSON.stringify({ type: "message", sessionId: routingSessionId, content, isStep: false } as OutboundMessage));
|
|
2546
2555
|
}
|
|
2547
2556
|
} else if (alreadyStreamed && shouldSpeak && voiceConfig.ttsProvider) {
|
|
2548
2557
|
try {
|
|
@@ -2552,7 +2561,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2552
2561
|
log.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
2553
2562
|
ws.send(JSON.stringify({
|
|
2554
2563
|
type: "message",
|
|
2555
|
-
sessionId:
|
|
2564
|
+
sessionId: routingSessionId,
|
|
2556
2565
|
content,
|
|
2557
2566
|
audio: base64Audio,
|
|
2558
2567
|
mimeType: audioOutput.mimeType,
|
|
@@ -2563,15 +2572,14 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2563
2572
|
}
|
|
2564
2573
|
}
|
|
2565
2574
|
} catch (error) {
|
|
2566
|
-
const unifiedSessionId = msg.sessionId;
|
|
2567
2575
|
// Detener typing aunque falle — nunca dejar el spinner infinito
|
|
2568
|
-
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId:
|
|
2576
|
+
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId: msg.sessionId } as OutboundMessage));
|
|
2569
2577
|
ws.send(JSON.stringify({
|
|
2570
2578
|
type: "error",
|
|
2571
|
-
sessionId:
|
|
2579
|
+
sessionId: msg.sessionId,
|
|
2572
2580
|
error: (error as Error).message,
|
|
2573
2581
|
} as OutboundMessage));
|
|
2574
|
-
log.error(`Error for session ${
|
|
2582
|
+
log.error(`Error for session ${msg.sessionId}: ${(error as Error).message}`);
|
|
2575
2583
|
}
|
|
2576
2584
|
});
|
|
2577
2585
|
|
|
@@ -2730,7 +2738,7 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2730
2738
|
process.exit(0);
|
|
2731
2739
|
});
|
|
2732
2740
|
|
|
2733
|
-
process.on("SIGHUP", async () => {
|
|
2741
|
+
if (process.platform !== "win32") process.on("SIGHUP", async () => {
|
|
2734
2742
|
log.info("Received SIGHUP, reloading configuration...");
|
|
2735
2743
|
try {
|
|
2736
2744
|
const newConfig = await loadConfig();
|
|
@@ -2741,4 +2749,4 @@ export async function startGateway(config: Config): Promise<void> {
|
|
|
2741
2749
|
log.error(`Failed to reload configuration: ${(error as Error).message}`);
|
|
2742
2750
|
}
|
|
2743
2751
|
});
|
|
2744
|
-
}
|
|
2752
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Los datos se guardan en $HIVE_HOME/tts/ (por defecto ~/.hive/tts/).
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { existsSync, mkdirSync, readdirSync, renameSync } from "fs"
|
|
7
|
+
import { existsSync, mkdirSync, readdirSync, renameSync, unlinkSync, rmSync } from "fs"
|
|
8
8
|
import { join } from "path"
|
|
9
9
|
import { homedir } from "os"
|
|
10
10
|
import {
|
|
@@ -37,16 +37,24 @@ async function extractTarGz(archivePath: string, destDir: string): Promise<void>
|
|
|
37
37
|
stderr: "inherit",
|
|
38
38
|
}).exited
|
|
39
39
|
if (code !== 0) throw new Error(`tar falló con código ${code}`)
|
|
40
|
-
|
|
40
|
+
unlinkSync(archivePath)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async function extractZip(archivePath: string, destDir: string): Promise<void> {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
let code: number
|
|
45
|
+
if (process.platform === "win32") {
|
|
46
|
+
code = await Bun.spawn(
|
|
47
|
+
["powershell", "-Command", `Expand-Archive -Path "${archivePath}" -DestinationPath "${destDir}" -Force`],
|
|
48
|
+
{ stdout: "inherit", stderr: "inherit" }
|
|
49
|
+
).exited
|
|
50
|
+
} else {
|
|
51
|
+
code = await Bun.spawn(["unzip", "-q", archivePath, "-d", destDir], {
|
|
52
|
+
stdout: "inherit",
|
|
53
|
+
stderr: "inherit",
|
|
54
|
+
}).exited
|
|
55
|
+
}
|
|
56
|
+
if (code !== 0) throw new Error(`Extracción ZIP falló con código ${code}`)
|
|
57
|
+
unlinkSync(archivePath)
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
/**
|
|
@@ -86,7 +94,7 @@ export async function runInstall(ttsRoot: string): Promise<void> {
|
|
|
86
94
|
for (const entry of readdirSync(tempDir)) {
|
|
87
95
|
renameSync(join(tempDir, entry), join(BIN_DIR, entry))
|
|
88
96
|
}
|
|
89
|
-
|
|
97
|
+
rmSync(tempDir, { recursive: true, force: true })
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
if (!existsSync(binaryPath)) {
|