@johpaz/hive-agents 0.0.39 → 0.0.40
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 +29 -69
- package/dist/hive.js +2522 -1927
- package/dist/tool-worker.js +1791 -1334
- package/dist/ui/assets/AgentCreateForm-b7xHyfNc.js +1 -0
- package/dist/ui/assets/AgentDetailPage-VHy3M7mI.js +1 -0
- package/dist/ui/assets/AgentNewPage-BnWImQMx.js +1 -0
- package/dist/ui/{dist/assets/AgentsPage-C-GSRk-N.js → assets/AgentsPage-WFy5abqx.js} +1 -1
- package/dist/ui/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/assets/{CanvasPage-Cvs5ctza.js → CanvasPage-B9zuIrTm.js} +1 -1
- package/dist/ui/assets/{ChannelsPage-C5m_L7P9.js → ChannelsPage-DiN3NvIM.js} +1 -1
- package/dist/ui/assets/{DashboardPage-CztbRQdm.js → DashboardPage-CHjARjVK.js} +1 -1
- package/dist/ui/assets/{LoginPage-OMsrx5oj.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/{dist/assets/LogsPage-CcYYwjgF.js → assets/LogsPage-DW8Nnqe6.js} +1 -1
- package/dist/ui/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/assets/{NotFound-GbAJDgoD.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{dist/assets/RecoverPage-CwB2ByCU.js → assets/RecoverPage-8hTjr_JU.js} +1 -1
- package/dist/ui/assets/SettingsPage-DNa0jOkA.js +9 -0
- package/dist/ui/assets/{SetupPage-DOVh1ldK.js → SetupPage-Bdm2irQG.js} +1 -1
- package/dist/ui/assets/WebChatPage-DElJg6P2.js +16 -0
- package/dist/ui/assets/accordion-CnLzKNHK.js +1 -0
- package/dist/ui/{dist/assets/alert-D_2Y3qjL.js → assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{dist/assets/alert-dialog-CpMxaNcu.js → assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/assets/{badge-CxTPR6_t.js → badge-ChENFgkC.js} +1 -1
- package/dist/ui/assets/chevron-down-DIosfU_U.js +1 -0
- package/dist/ui/assets/chevron-up-CI-W21Fy.js +1 -0
- package/dist/ui/{dist/assets/dialog-DfS3idb3.js → assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/assets/{dropdown-menu-BdCbAW1z.js → dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/assets/{es-Cz5h9_84.js → es-ecSKCyB6.js} +1 -1
- package/dist/ui/assets/index-CawKP29y.js +116 -0
- package/dist/ui/assets/index-DIcsEkyd.css +2 -0
- package/dist/ui/{dist/assets/label-byJkqOYq.js → assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/assets/useProviders-Dlizq_8q.js +1 -0
- package/dist/ui/dist/assets/AgentCreateForm-b7xHyfNc.js +1 -0
- package/dist/ui/dist/assets/AgentDetailPage-VHy3M7mI.js +1 -0
- package/dist/ui/dist/assets/AgentNewPage-BnWImQMx.js +1 -0
- package/dist/ui/{assets/AgentsPage-C-GSRk-N.js → dist/assets/AgentsPage-WFy5abqx.js} +1 -1
- package/dist/ui/dist/assets/ApiClientPage-BV7zLIL7.js +3 -0
- package/dist/ui/dist/assets/{CanvasPage-Cvs5ctza.js → CanvasPage-B9zuIrTm.js} +1 -1
- package/dist/ui/dist/assets/{ChannelsPage-C5m_L7P9.js → ChannelsPage-DiN3NvIM.js} +1 -1
- package/dist/ui/dist/assets/{DashboardPage-CztbRQdm.js → DashboardPage-CHjARjVK.js} +1 -1
- package/dist/ui/dist/assets/{LoginPage-OMsrx5oj.js → LoginPage-Dwd_XxoU.js} +1 -1
- package/dist/ui/{assets/LogsPage-CcYYwjgF.js → dist/assets/LogsPage-DW8Nnqe6.js} +1 -1
- package/dist/ui/dist/assets/MeetingPage-D3bkiKYt.js +1 -0
- package/dist/ui/dist/assets/{NotFound-GbAJDgoD.js → NotFound-BIUDlIXU.js} +1 -1
- package/dist/ui/dist/assets/ProvidersPage-UqsDAxPQ.js +1 -0
- package/dist/ui/{assets/RecoverPage-CwB2ByCU.js → dist/assets/RecoverPage-8hTjr_JU.js} +1 -1
- package/dist/ui/dist/assets/SettingsPage-DNa0jOkA.js +9 -0
- package/dist/ui/dist/assets/{SetupPage-DOVh1ldK.js → SetupPage-Bdm2irQG.js} +1 -1
- package/dist/ui/dist/assets/WebChatPage-DElJg6P2.js +16 -0
- package/dist/ui/dist/assets/accordion-CnLzKNHK.js +1 -0
- package/dist/ui/{assets/alert-D_2Y3qjL.js → dist/assets/alert-DylmSCDJ.js} +1 -1
- package/dist/ui/{assets/alert-dialog-CpMxaNcu.js → dist/assets/alert-dialog-DNNWN_SI.js} +1 -1
- package/dist/ui/dist/assets/{badge-CxTPR6_t.js → badge-ChENFgkC.js} +1 -1
- package/dist/ui/dist/assets/chevron-down-DIosfU_U.js +1 -0
- package/dist/ui/dist/assets/chevron-up-CI-W21Fy.js +1 -0
- package/dist/ui/{assets/dialog-DfS3idb3.js → dist/assets/dialog-BJ-npIv8.js} +1 -1
- package/dist/ui/dist/assets/{dropdown-menu-BdCbAW1z.js → dropdown-menu-DDiaHg5y.js} +1 -1
- package/dist/ui/dist/assets/{es-Cz5h9_84.js → es-ecSKCyB6.js} +1 -1
- package/dist/ui/dist/assets/index-CawKP29y.js +116 -0
- package/dist/ui/dist/assets/index-DIcsEkyd.css +2 -0
- package/dist/ui/{assets/label-byJkqOYq.js → dist/assets/label-Bi6udtSd.js} +1 -1
- package/dist/ui/dist/assets/select-BQCOjM2j.js +1 -0
- package/dist/ui/dist/assets/useProviders-Dlizq_8q.js +1 -0
- package/dist/ui/dist/index.html +4 -4
- package/dist/ui/index.html +4 -4
- package/package.json +1 -1
- package/packages/cli/src/commands/gateway.ts +1 -1
- package/packages/cli/src/commands/onboard.ts +27 -1
- package/packages/core/src/agent/agent-loop.ts +104 -2
- package/packages/core/src/agent/context-compiler.ts +6 -0
- package/packages/core/src/agent/llm-client.ts +2 -0
- package/packages/core/src/agent/llm-providers/hiveagents.ts +248 -0
- package/packages/core/src/agent/llm-providers/interface.ts +2 -0
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +49 -25
- package/packages/core/src/agent/providers/index.ts +3 -2
- package/packages/core/src/agent/stuck-loop.ts +90 -14
- package/packages/core/src/channels/base.ts +7 -1
- package/packages/core/src/config/loader.ts +1 -1
- package/packages/core/src/gateway/routes/providers.ts +56 -0
- package/packages/core/src/gateway/server.ts +120 -55
- package/packages/core/src/gateway/slash-commands.ts +7 -1
- package/packages/core/src/storage/onboarding.ts +28 -0
- package/packages/core/src/storage/seed.ts +14 -0
- package/packages/skills/src/bundled-data.generated.ts +1357 -1357
- package/dist/ui/assets/AgentCreateForm-BTCzFbca.js +0 -1
- package/dist/ui/assets/AgentDetailPage-o27TRSVw.js +0 -1
- package/dist/ui/assets/AgentNewPage-400cCpYt.js +0 -1
- package/dist/ui/assets/ApiClientPage-BOTpz6oP.js +0 -3
- package/dist/ui/assets/MeetingPage-CrKVAfe6.js +0 -1
- package/dist/ui/assets/ProvidersPage-uqPcZUSV.js +0 -1
- package/dist/ui/assets/SettingsPage-DKLlye0z.js +0 -9
- package/dist/ui/assets/WebChatPage-c-7S9jnT.js +0 -16
- package/dist/ui/assets/accordion-DAbcVQCn.js +0 -1
- package/dist/ui/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/assets/index-CmGm_r89.js +0 -116
- package/dist/ui/assets/index-T7HgphSn.css +0 -2
- package/dist/ui/assets/select-Cl16QYa_.js +0 -1
- package/dist/ui/assets/useProviders-eEri6BAc.js +0 -1
- package/dist/ui/dist/assets/AgentCreateForm-BTCzFbca.js +0 -1
- package/dist/ui/dist/assets/AgentDetailPage-o27TRSVw.js +0 -1
- package/dist/ui/dist/assets/AgentNewPage-400cCpYt.js +0 -1
- package/dist/ui/dist/assets/ApiClientPage-BOTpz6oP.js +0 -3
- package/dist/ui/dist/assets/MeetingPage-CrKVAfe6.js +0 -1
- package/dist/ui/dist/assets/ProvidersPage-uqPcZUSV.js +0 -1
- package/dist/ui/dist/assets/SettingsPage-DKLlye0z.js +0 -9
- package/dist/ui/dist/assets/WebChatPage-c-7S9jnT.js +0 -16
- package/dist/ui/dist/assets/accordion-DAbcVQCn.js +0 -1
- package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +0 -1
- package/dist/ui/dist/assets/index-CmGm_r89.js +0 -116
- package/dist/ui/dist/assets/index-T7HgphSn.css +0 -2
- package/dist/ui/dist/assets/select-Cl16QYa_.js +0 -1
- package/dist/ui/dist/assets/useProviders-eEri6BAc.js +0 -1
- /package/dist/ui/assets/{card-CXAm46at.js → card-DFKnZ6ky.js} +0 -0
- /package/dist/ui/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
- /package/dist/ui/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
- /package/dist/ui/assets/{circle-x-Bv6WrUJo.js → circle-x-DjLkFDO8.js} +0 -0
- /package/dist/ui/assets/{copy-dU94ZGsi.js → copy-Bu5d7C-0.js} +0 -0
- /package/dist/ui/assets/{cpu-DSpPVLAz.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/assets/{download-D9ZyUZZR.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/assets/{external-link-CHPbUorN.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/assets/{eye-epHJZ_nQ.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/assets/{file-text-BEjEmgby.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/assets/{folder-open-iQMHVEqS.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/assets/{format-oFACFaca.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/assets/{gateway-url-iG-C6Agn.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/assets/{gauge-D0_GMEcq.js → gauge-B8Tj43rC.js} +0 -0
- /package/dist/ui/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
- /package/dist/ui/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
- /package/dist/ui/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
- /package/dist/ui/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
- /package/dist/ui/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
- /package/dist/ui/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
- /package/dist/ui/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
- /package/dist/ui/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
- /package/dist/ui/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
- /package/dist/ui/assets/{progress-Dtz-Mzys.js → progress-D5c-Eilm.js} +0 -0
- /package/dist/ui/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
- /package/dist/ui/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
- /package/dist/ui/assets/{scroll-area-BXtLsE9E.js → scroll-area-CihOx0cb.js} +0 -0
- /package/dist/ui/assets/{search-BGmPJ-6L.js → search-DzDptO9s.js} +0 -0
- /package/dist/ui/assets/{send-BuQcUO-R.js → send-BPk9XbIq.js} +0 -0
- /package/dist/ui/assets/{settings-CcMGI1iU.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/assets/{shield-C-05qB-2.js → shield-CxhcUT39.js} +0 -0
- /package/dist/ui/assets/{slider-D2I0qven.js → slider-bcUiUfx0.js} +0 -0
- /package/dist/ui/assets/{sparkles-D6fx8JC5.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/assets/{switch-h2SfQX4B.js → switch-BR30E4ej.js} +0 -0
- /package/dist/ui/assets/{table-CVkIRJKK.js → table-B3aGEaVp.js} +0 -0
- /package/dist/ui/assets/{tabs-C619jxbO.js → tabs-LQidMKRS.js} +0 -0
- /package/dist/ui/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/assets/{textarea-wvA-FDjO.js → textarea-B6Z1Zc6W.js} +0 -0
- /package/dist/ui/assets/{trash-2-BHRa5ft9.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/assets/{triangle-alert-D4nwAVbc.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/assets/{vendor-router-pCP7sjma.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/assets/{volume-2-B6tkRy2u.js → volume-2-BekVQl6P.js} +0 -0
- /package/dist/ui/assets/{zap-QO7iWMRg.js → zap-B4RaNNO5.js} +0 -0
- /package/dist/ui/dist/assets/{card-CXAm46at.js → card-DFKnZ6ky.js} +0 -0
- /package/dist/ui/dist/assets/{circle-alert-CyHDwUj8.js → circle-alert-KuAm2FWh.js} +0 -0
- /package/dist/ui/dist/assets/{circle-check-Bb54Ebmu.js → circle-check-6Ard1-2z.js} +0 -0
- /package/dist/ui/dist/assets/{circle-x-Bv6WrUJo.js → circle-x-DjLkFDO8.js} +0 -0
- /package/dist/ui/dist/assets/{copy-dU94ZGsi.js → copy-Bu5d7C-0.js} +0 -0
- /package/dist/ui/dist/assets/{cpu-DSpPVLAz.js → cpu-KDy6-FAI.js} +0 -0
- /package/dist/ui/dist/assets/{download-D9ZyUZZR.js → download-Cjbk4Rek.js} +0 -0
- /package/dist/ui/dist/assets/{external-link-CHPbUorN.js → external-link-6sTlRDUR.js} +0 -0
- /package/dist/ui/dist/assets/{eye-epHJZ_nQ.js → eye-Df8o0tkC.js} +0 -0
- /package/dist/ui/dist/assets/{file-text-BEjEmgby.js → file-text-lnxnjBp0.js} +0 -0
- /package/dist/ui/dist/assets/{folder-open-iQMHVEqS.js → folder-open-DJBLDFjv.js} +0 -0
- /package/dist/ui/dist/assets/{format-oFACFaca.js → format-BwdV8bB5.js} +0 -0
- /package/dist/ui/dist/assets/{gateway-url-iG-C6Agn.js → gateway-url-DwzPmoc8.js} +0 -0
- /package/dist/ui/dist/assets/{gauge-D0_GMEcq.js → gauge-B8Tj43rC.js} +0 -0
- /package/dist/ui/dist/assets/{hexagon-DsGOUl-H.js → hexagon-6L79pgVK.js} +0 -0
- /package/dist/ui/dist/assets/{history-BSG-Ypqf.js → history-CAF_R34_.js} +0 -0
- /package/dist/ui/dist/assets/{info-NwLoa2Mj.js → info-WjromB4Y.js} +0 -0
- /package/dist/ui/dist/assets/{key-3EP0dhkT.js → key-DyKOoQh5.js} +0 -0
- /package/dist/ui/dist/assets/{loader-circle-CZNax6kS.js → loader-circle-BmBOgYze.js} +0 -0
- /package/dist/ui/dist/assets/{lock-Ei1_J-Nq.js → lock-BS6OLXPv.js} +0 -0
- /package/dist/ui/dist/assets/{pause-BUqah9Bi.js → pause-VqeUmp2Z.js} +0 -0
- /package/dist/ui/dist/assets/{play-NcZ4swwL.js → play-zJpWuhrr.js} +0 -0
- /package/dist/ui/dist/assets/{plus-CX1xyhp5.js → plus-BZQX26Dr.js} +0 -0
- /package/dist/ui/dist/assets/{progress-Dtz-Mzys.js → progress-D5c-Eilm.js} +0 -0
- /package/dist/ui/dist/assets/{refresh-cw-DaYdjQFk.js → refresh-cw-CCzDCAuz.js} +0 -0
- /package/dist/ui/dist/assets/{save-CUdYyHNy.js → save-hUmZhceG.js} +0 -0
- /package/dist/ui/dist/assets/{scroll-area-BXtLsE9E.js → scroll-area-CihOx0cb.js} +0 -0
- /package/dist/ui/dist/assets/{search-BGmPJ-6L.js → search-DzDptO9s.js} +0 -0
- /package/dist/ui/dist/assets/{send-BuQcUO-R.js → send-BPk9XbIq.js} +0 -0
- /package/dist/ui/dist/assets/{settings-CcMGI1iU.js → settings-BGfrZ_zM.js} +0 -0
- /package/dist/ui/dist/assets/{shield-C-05qB-2.js → shield-CxhcUT39.js} +0 -0
- /package/dist/ui/dist/assets/{slider-D2I0qven.js → slider-bcUiUfx0.js} +0 -0
- /package/dist/ui/dist/assets/{sparkles-D6fx8JC5.js → sparkles-BhwlS1pc.js} +0 -0
- /package/dist/ui/dist/assets/{square-BD81nFtN.js → square-DMNWw4Hi.js} +0 -0
- /package/dist/ui/dist/assets/{switch-h2SfQX4B.js → switch-BR30E4ej.js} +0 -0
- /package/dist/ui/dist/assets/{table-CVkIRJKK.js → table-B3aGEaVp.js} +0 -0
- /package/dist/ui/dist/assets/{tabs-C619jxbO.js → tabs-LQidMKRS.js} +0 -0
- /package/dist/ui/dist/assets/{terminal-DN38Q456.js → terminal--7G943As.js} +0 -0
- /package/dist/ui/dist/assets/{textarea-wvA-FDjO.js → textarea-B6Z1Zc6W.js} +0 -0
- /package/dist/ui/dist/assets/{trash-2-BHRa5ft9.js → trash-2-xD2o4SgX.js} +0 -0
- /package/dist/ui/dist/assets/{triangle-alert-D4nwAVbc.js → triangle-alert-pVIJGjga.js} +0 -0
- /package/dist/ui/dist/assets/{vendor-router-pCP7sjma.js → vendor-router-gqiZ7xhx.js} +0 -0
- /package/dist/ui/dist/assets/{volume-2-B6tkRy2u.js → volume-2-BekVQl6P.js} +0 -0
- /package/dist/ui/dist/assets/{zap-QO7iWMRg.js → zap-B4RaNNO5.js} +0 -0
package/dist/tool-worker.js
CHANGED
|
@@ -5416,7 +5416,7 @@ var init_loader = __esm(() => {
|
|
|
5416
5416
|
tools: ToolRestrictionsSchema.optional()
|
|
5417
5417
|
});
|
|
5418
5418
|
ModelsConfigSchema = object({
|
|
5419
|
-
defaultProvider: _enum(["openai", "anthropic", "gemini", "mistral", "kimi", "ollama", "openrouter", "deepseek"]).optional(),
|
|
5419
|
+
defaultProvider: _enum(["openai", "anthropic", "gemini", "mistral", "kimi", "ollama", "openrouter", "deepseek", "hiveagents"]).optional(),
|
|
5420
5420
|
defaults: record(string2(), string2()).optional(),
|
|
5421
5421
|
providers: record(string2(), ProviderConfigSchema).optional()
|
|
5422
5422
|
});
|
|
@@ -10044,7 +10044,8 @@ var init_interface = __esm(() => {
|
|
|
10044
10044
|
nvidia: "https://integrate.api.nvidia.com/v1",
|
|
10045
10045
|
qwen: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
|
10046
10046
|
minimax: "https://api.minimaxi.com/v1",
|
|
10047
|
-
"opencode-go": "https://opencode.ai/zen/go/v1"
|
|
10047
|
+
"opencode-go": "https://opencode.ai/zen/go/v1",
|
|
10048
|
+
hiveagents: "https://llm.hiveagents.io/v1"
|
|
10048
10049
|
};
|
|
10049
10050
|
DEFAULT_PROFILE = {
|
|
10050
10051
|
normalizeToolNames: false,
|
|
@@ -10065,7 +10066,8 @@ var init_interface = __esm(() => {
|
|
|
10065
10066
|
qwen: { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] },
|
|
10066
10067
|
"local-llama": { ...DEFAULT_PROFILE },
|
|
10067
10068
|
minimax: { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] },
|
|
10068
|
-
"opencode-go": { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] }
|
|
10069
|
+
"opencode-go": { ...DEFAULT_PROFILE, normalizeToolNames: true, retryWithoutToolsOnCodes: [400, 422] },
|
|
10070
|
+
hiveagents: { ...DEFAULT_PROFILE, retryWithoutToolsOnCodes: [400, 422] }
|
|
10069
10071
|
};
|
|
10070
10072
|
NO_TOOL_MODELS = new Set([
|
|
10071
10073
|
"deepseek-reasoner",
|
|
@@ -50997,8 +50999,15 @@ class OpenAICompatBase {
|
|
|
50997
50999
|
isLocalProvider() {
|
|
50998
51000
|
return false;
|
|
50999
51001
|
}
|
|
51002
|
+
async resolveOpenAIClient(apiKey, baseURL) {
|
|
51003
|
+
const { default: OpenAI2 } = await Promise.resolve().then(() => (init_openai(), exports_openai));
|
|
51004
|
+
return new OpenAI2({ apiKey, baseURL });
|
|
51005
|
+
}
|
|
51000
51006
|
async beforeCall(_options) {}
|
|
51001
51007
|
injectToolsIntoPrompt(_body, _preparedTools) {}
|
|
51008
|
+
modifyRequestBody(body, _options) {
|
|
51009
|
+
return body;
|
|
51010
|
+
}
|
|
51002
51011
|
_convertContentPart(part) {
|
|
51003
51012
|
switch (part.type) {
|
|
51004
51013
|
case "text":
|
|
@@ -51021,7 +51030,6 @@ class OpenAICompatBase {
|
|
|
51021
51030
|
return msg;
|
|
51022
51031
|
}
|
|
51023
51032
|
async call(options) {
|
|
51024
|
-
const { default: OpenAI2 } = await Promise.resolve().then(() => (init_openai(), exports_openai));
|
|
51025
51033
|
const baseURL = options.baseUrl?.trim() || OPENAI_COMPAT_BASE_URLS[this.providerName] || undefined;
|
|
51026
51034
|
const isLocal = this.isLocalProvider();
|
|
51027
51035
|
await this.beforeCall(options);
|
|
@@ -51029,7 +51037,7 @@ class OpenAICompatBase {
|
|
|
51029
51037
|
if (!apiKey) {
|
|
51030
51038
|
throw new Error(`API key missing for provider: ${this.providerName}. Configure it in Settings \u2192 Providers.`);
|
|
51031
51039
|
}
|
|
51032
|
-
const client =
|
|
51040
|
+
const client = await this.resolveOpenAIClient(apiKey, baseURL);
|
|
51033
51041
|
const sanitized = sanitizeMessages(options.messages);
|
|
51034
51042
|
const rawMessages = this.needsReasoningRoundtrip() ? sanitized : sanitized.map(({ reasoning_content: _rc, ...rest }) => rest);
|
|
51035
51043
|
const messagesForProvider = rawMessages.map((m2) => this._convertMessage(m2));
|
|
@@ -51076,7 +51084,7 @@ class OpenAICompatBase {
|
|
|
51076
51084
|
}
|
|
51077
51085
|
let response;
|
|
51078
51086
|
try {
|
|
51079
|
-
response = await client.chat.completions.create(body);
|
|
51087
|
+
response = await client.chat.completions.create(this.modifyRequestBody(body, options));
|
|
51080
51088
|
} catch (err) {
|
|
51081
51089
|
const status = err?.status ?? err?.response?.status;
|
|
51082
51090
|
const errMsg = (err?.error?.message ?? err?.message ?? "").toLowerCase();
|
|
@@ -51086,7 +51094,7 @@ class OpenAICompatBase {
|
|
|
51086
51094
|
delete bodyNoTools.tools;
|
|
51087
51095
|
delete bodyNoTools.tool_choice;
|
|
51088
51096
|
delete bodyNoTools.parallel_tool_calls;
|
|
51089
|
-
response = await client.chat.completions.create(bodyNoTools);
|
|
51097
|
+
response = await client.chat.completions.create(this.modifyRequestBody(bodyNoTools, options));
|
|
51090
51098
|
} else if (status === 400 && (errMsg.includes("context length") || errMsg.includes("input_tokens") || errMsg.includes("maximum input length"))) {
|
|
51091
51099
|
log26.warn(`[llm-client] ${this.providerName}: context overflow \u2014 compacting messages and retrying`);
|
|
51092
51100
|
const compacted = [...body.messages];
|
|
@@ -51105,7 +51113,7 @@ class OpenAICompatBase {
|
|
|
51105
51113
|
if (body.max_tokens)
|
|
51106
51114
|
body.max_tokens = Math.min(body.max_tokens, 4096);
|
|
51107
51115
|
log26.info(`[llm-client] ${this.providerName}: compacted ${compacted.length} msgs \u2192 ${body.messages.length} msgs, max_tokens=${body.max_tokens}`);
|
|
51108
|
-
response = await client.chat.completions.create(body);
|
|
51116
|
+
response = await client.chat.completions.create(this.modifyRequestBody(body, options));
|
|
51109
51117
|
} else {
|
|
51110
51118
|
throw err;
|
|
51111
51119
|
}
|
|
@@ -51142,7 +51150,7 @@ class OpenAICompatBase {
|
|
|
51142
51150
|
async _streamCall(client, body, options, toolNameMap, sendTools, profile) {
|
|
51143
51151
|
let stream;
|
|
51144
51152
|
try {
|
|
51145
|
-
stream = await client.chat.completions.create({ ...body, stream: true });
|
|
51153
|
+
stream = await client.chat.completions.create({ ...this.modifyRequestBody(body, options), stream: true });
|
|
51146
51154
|
} catch (err) {
|
|
51147
51155
|
const status = err?.status ?? err?.response?.status;
|
|
51148
51156
|
const errMsg = (err?.error?.message ?? err?.message ?? "").toLowerCase();
|
|
@@ -51152,7 +51160,7 @@ class OpenAICompatBase {
|
|
|
51152
51160
|
delete bodyNoTools.tools;
|
|
51153
51161
|
delete bodyNoTools.tool_choice;
|
|
51154
51162
|
delete bodyNoTools.parallel_tool_calls;
|
|
51155
|
-
stream = await client.chat.completions.create({ ...bodyNoTools, stream: true });
|
|
51163
|
+
stream = await client.chat.completions.create({ ...this.modifyRequestBody(bodyNoTools, options), stream: true });
|
|
51156
51164
|
} else if (status === 400 && (errMsg.includes("context length") || errMsg.includes("input_tokens") || errMsg.includes("maximum input length"))) {
|
|
51157
51165
|
log26.warn(`[llm-client] ${this.providerName}: context overflow \u2014 compacting messages and retrying stream`);
|
|
51158
51166
|
const compacted = [...body.messages];
|
|
@@ -51171,7 +51179,7 @@ class OpenAICompatBase {
|
|
|
51171
51179
|
if (body.max_tokens)
|
|
51172
51180
|
body.max_tokens = Math.min(body.max_tokens, 4096);
|
|
51173
51181
|
log26.info(`[llm-client] ${this.providerName}: compacted ${compacted.length} msgs \u2192 ${body.messages.length} msgs, max_tokens=${body.max_tokens}`);
|
|
51174
|
-
stream = await client.chat.completions.create({ ...body, stream: true });
|
|
51182
|
+
stream = await client.chat.completions.create({ ...this.modifyRequestBody(body, options), stream: true });
|
|
51175
51183
|
} else {
|
|
51176
51184
|
throw err;
|
|
51177
51185
|
}
|
|
@@ -51255,13 +51263,21 @@ function extractToolCallsFromText(content, toolNameMap, knownToolNames) {
|
|
|
51255
51263
|
while ((match = regex.exec(content)) !== null) {
|
|
51256
51264
|
try {
|
|
51257
51265
|
const json = JSON.parse(match[1]);
|
|
51258
|
-
|
|
51266
|
+
const calls = Array.isArray(json) ? json : [json];
|
|
51267
|
+
for (const call of calls) {
|
|
51268
|
+
if (!call)
|
|
51269
|
+
continue;
|
|
51270
|
+
const fn = call.function || call;
|
|
51271
|
+
const name = fn.name ?? call.name;
|
|
51272
|
+
let args = fn.arguments ?? call.arguments ?? call.parameters;
|
|
51273
|
+
if (!name)
|
|
51274
|
+
continue;
|
|
51259
51275
|
tool_calls.push({
|
|
51260
51276
|
id: crypto.randomUUID(),
|
|
51261
51277
|
type: "function",
|
|
51262
51278
|
function: {
|
|
51263
|
-
name: toolNameMap.get(
|
|
51264
|
-
arguments: typeof
|
|
51279
|
+
name: toolNameMap.get(name) ?? name,
|
|
51280
|
+
arguments: typeof args === "object" ? JSON.stringify(args) : args || "{}"
|
|
51265
51281
|
}
|
|
51266
51282
|
});
|
|
51267
51283
|
extractedContent = extractedContent.replace(match[0], "").trim();
|
|
@@ -51271,19 +51287,28 @@ function extractToolCallsFromText(content, toolNameMap, knownToolNames) {
|
|
|
51271
51287
|
}
|
|
51272
51288
|
if (tool_calls.length === 0 && knownToolNames && knownToolNames.size > 0) {
|
|
51273
51289
|
try {
|
|
51274
|
-
const
|
|
51275
|
-
const
|
|
51276
|
-
|
|
51277
|
-
|
|
51278
|
-
|
|
51279
|
-
|
|
51280
|
-
|
|
51281
|
-
|
|
51282
|
-
|
|
51283
|
-
|
|
51284
|
-
|
|
51285
|
-
|
|
51286
|
-
|
|
51290
|
+
const trimmed = content.trim();
|
|
51291
|
+
const jsonText = trimmed.replace(/^```(?:json|tool_call)?\s*|\s*```$/g, "").trim();
|
|
51292
|
+
const json = JSON.parse(jsonText);
|
|
51293
|
+
const calls = Array.isArray(json) ? json : [json];
|
|
51294
|
+
for (const call of calls) {
|
|
51295
|
+
if (!call)
|
|
51296
|
+
continue;
|
|
51297
|
+
const fn = call.function || call;
|
|
51298
|
+
const name = fn.name ?? call.name;
|
|
51299
|
+
let args = fn.arguments ?? call.arguments ?? call.parameters;
|
|
51300
|
+
const resolvedName = toolNameMap.get(name) ?? name;
|
|
51301
|
+
if (name && knownToolNames.has(resolvedName) && (args !== undefined || calls.length === 1)) {
|
|
51302
|
+
tool_calls.push({
|
|
51303
|
+
id: crypto.randomUUID(),
|
|
51304
|
+
type: "function",
|
|
51305
|
+
function: {
|
|
51306
|
+
name: resolvedName,
|
|
51307
|
+
arguments: typeof args === "object" ? JSON.stringify(args) : args || "{}"
|
|
51308
|
+
}
|
|
51309
|
+
});
|
|
51310
|
+
extractedContent = "";
|
|
51311
|
+
}
|
|
51287
51312
|
}
|
|
51288
51313
|
} catch {}
|
|
51289
51314
|
}
|
|
@@ -51753,6 +51778,197 @@ var init_opencode_go = __esm(() => {
|
|
|
51753
51778
|
};
|
|
51754
51779
|
});
|
|
51755
51780
|
|
|
51781
|
+
// packages/core/src/agent/llm-providers/hiveagents.ts
|
|
51782
|
+
function getApiBase(baseUrl) {
|
|
51783
|
+
return baseUrl?.replace(/\/v1\/?$/, "") || DEFAULT_BASE;
|
|
51784
|
+
}
|
|
51785
|
+
function getAuthHeaders(apiKey) {
|
|
51786
|
+
return {
|
|
51787
|
+
"Content-Type": "application/json",
|
|
51788
|
+
Authorization: `Bearer ${apiKey}`
|
|
51789
|
+
};
|
|
51790
|
+
}
|
|
51791
|
+
async function loadHiveAgentsModel(modelId, apiKey, baseUrl, ctx = HIVEAGENTS_DEFAULT_LOAD_CTX) {
|
|
51792
|
+
const apiBase = getApiBase(baseUrl);
|
|
51793
|
+
const headers = getAuthHeaders(apiKey);
|
|
51794
|
+
const loadBody = {
|
|
51795
|
+
model: modelId,
|
|
51796
|
+
config: { ctx }
|
|
51797
|
+
};
|
|
51798
|
+
try {
|
|
51799
|
+
log29.info(`[hiveagents] \u2192 POST ${apiBase}/api/load`);
|
|
51800
|
+
log29.info(`[hiveagents] \u2192 Body: ${JSON.stringify(loadBody)}`);
|
|
51801
|
+
const res = await fetch(`${apiBase}/api/load`, {
|
|
51802
|
+
method: "POST",
|
|
51803
|
+
headers,
|
|
51804
|
+
body: JSON.stringify(loadBody),
|
|
51805
|
+
signal: AbortSignal.timeout(HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS)
|
|
51806
|
+
});
|
|
51807
|
+
const responseText = await res.text().catch(() => "");
|
|
51808
|
+
if (!res.ok) {
|
|
51809
|
+
const isTransientCloudflareError = [502, 503, 504, 524, 530].includes(res.status);
|
|
51810
|
+
if (isTransientCloudflareError) {
|
|
51811
|
+
log29.warn(`[hiveagents] \u2190 Load request hit transient error (HTTP ${res.status}); backend may still be loading`);
|
|
51812
|
+
return { success: true, loading: true };
|
|
51813
|
+
}
|
|
51814
|
+
log29.error(`[hiveagents] \u2190 Load failed: HTTP ${res.status} ${res.statusText} \u2014 ${responseText}`);
|
|
51815
|
+
return { success: false, error: `Load failed: HTTP ${res.status} \u2014 ${responseText || res.statusText}` };
|
|
51816
|
+
}
|
|
51817
|
+
log29.info(`[hiveagents] \u2190 Load accepted: ${responseText}`);
|
|
51818
|
+
return { success: true };
|
|
51819
|
+
} catch (err) {
|
|
51820
|
+
const msg = err.message || "";
|
|
51821
|
+
if (msg.includes("timed out") || msg.includes("abort") || msg.includes("AbortError")) {
|
|
51822
|
+
log29.warn(`[hiveagents] \u2190 Load request timed out after ${HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS}ms; backend may still be loading`);
|
|
51823
|
+
return { success: true, loading: true };
|
|
51824
|
+
}
|
|
51825
|
+
return { success: false, error: msg };
|
|
51826
|
+
}
|
|
51827
|
+
}
|
|
51828
|
+
async function getHiveAgentsModelStatus(apiKey, baseUrl) {
|
|
51829
|
+
const apiBase = getApiBase(baseUrl);
|
|
51830
|
+
const headers = getAuthHeaders(apiKey);
|
|
51831
|
+
try {
|
|
51832
|
+
const res = await fetch(`${apiBase}/api/status`, { headers });
|
|
51833
|
+
if (!res.ok)
|
|
51834
|
+
return { loaded: false };
|
|
51835
|
+
const data = await res.json();
|
|
51836
|
+
return {
|
|
51837
|
+
loaded: !!data.loaded,
|
|
51838
|
+
model: data.model
|
|
51839
|
+
};
|
|
51840
|
+
} catch {
|
|
51841
|
+
return { loaded: false };
|
|
51842
|
+
}
|
|
51843
|
+
}
|
|
51844
|
+
var log29, DEFAULT_BASE = "https://llm.hiveagents.io", HIVEAGENTS_DEFAULT_LOAD_CTX = 50000, BLOCKED_HEADERS, HIVEAGENTS_LOAD_FETCH_TIMEOUT_MS = 90000, HiveAgentsProvider;
|
|
51845
|
+
var init_hiveagents = __esm(() => {
|
|
51846
|
+
init_logger();
|
|
51847
|
+
init_openai_compat_base();
|
|
51848
|
+
log29 = logger.child("llm-client");
|
|
51849
|
+
BLOCKED_HEADERS = [
|
|
51850
|
+
"user-agent",
|
|
51851
|
+
"x-stainless-lang",
|
|
51852
|
+
"x-stainless-package-version",
|
|
51853
|
+
"x-stainless-runtime",
|
|
51854
|
+
"x-stainless-runtime-version",
|
|
51855
|
+
"x-stainless-arch",
|
|
51856
|
+
"x-stainless-os"
|
|
51857
|
+
];
|
|
51858
|
+
HiveAgentsProvider = class HiveAgentsProvider extends OpenAICompatBase {
|
|
51859
|
+
_currentModelId = "";
|
|
51860
|
+
constructor() {
|
|
51861
|
+
super("hiveagents");
|
|
51862
|
+
}
|
|
51863
|
+
_isGemma4(modelId) {
|
|
51864
|
+
return /^gemma-?4/i.test(modelId);
|
|
51865
|
+
}
|
|
51866
|
+
_isQwen3(modelId) {
|
|
51867
|
+
return /^qwen3?/i.test(modelId);
|
|
51868
|
+
}
|
|
51869
|
+
async resolveOpenAIClient(apiKey, baseURL) {
|
|
51870
|
+
const { default: OpenAI2 } = await Promise.resolve().then(() => (init_openai(), exports_openai));
|
|
51871
|
+
return new OpenAI2({
|
|
51872
|
+
apiKey,
|
|
51873
|
+
baseURL,
|
|
51874
|
+
fetch: async (url, init) => {
|
|
51875
|
+
const headers = new Headers(init?.headers);
|
|
51876
|
+
for (const h of BLOCKED_HEADERS)
|
|
51877
|
+
headers.delete(h);
|
|
51878
|
+
const headersObj = {};
|
|
51879
|
+
headers.forEach((v2, k2) => {
|
|
51880
|
+
headersObj[k2] = k2.toLowerCase() === "authorization" ? `Bearer \u2022\u2022\u2022\u2022${v2.slice(-6)}` : v2;
|
|
51881
|
+
});
|
|
51882
|
+
log29.info(`[hiveagents] \u2192 POST ${url}`);
|
|
51883
|
+
log29.info(`[hiveagents] \u2192 Headers: ${JSON.stringify(headersObj)}`);
|
|
51884
|
+
if (init?.body) {
|
|
51885
|
+
try {
|
|
51886
|
+
const parsed = JSON.parse(init.body);
|
|
51887
|
+
const summary = { model: parsed.model, messages: parsed.messages?.length, tools: parsed.tools?.length, max_tokens: parsed.max_tokens, temperature: parsed.temperature, tool_choice: parsed.tool_choice, extra_body: parsed.extra_body };
|
|
51888
|
+
log29.info(`[hiveagents] \u2192 Body summary: ${JSON.stringify(summary)}`);
|
|
51889
|
+
} catch {}
|
|
51890
|
+
}
|
|
51891
|
+
const res = await fetch(url, { ...init, headers });
|
|
51892
|
+
log29.info(`[hiveagents] \u2190 Response: ${res.status} ${res.statusText}`);
|
|
51893
|
+
return res;
|
|
51894
|
+
}
|
|
51895
|
+
});
|
|
51896
|
+
}
|
|
51897
|
+
async call(options) {
|
|
51898
|
+
const realModelId = options.model.replace(/^hiveagents\//i, "");
|
|
51899
|
+
if (realModelId && realModelId !== "local") {
|
|
51900
|
+
await this._ensureModelLoaded(realModelId, options);
|
|
51901
|
+
}
|
|
51902
|
+
this._currentModelId = realModelId;
|
|
51903
|
+
let callOptions = { ...options, model: "hiveagents/local" };
|
|
51904
|
+
if (this._isQwen3(realModelId) && options.thinking?.enabled === false) {
|
|
51905
|
+
const msgs = callOptions.messages.map((m2) => ({ ...m2 }));
|
|
51906
|
+
const sysMsg = msgs.find((m2) => m2.role === "system");
|
|
51907
|
+
if (sysMsg && typeof sysMsg.content === "string") {
|
|
51908
|
+
if (!sysMsg.content.startsWith("/no_think"))
|
|
51909
|
+
sysMsg.content = `/no_think
|
|
51910
|
+
` + sysMsg.content;
|
|
51911
|
+
} else {
|
|
51912
|
+
msgs.unshift({ role: "system", content: "/no_think" });
|
|
51913
|
+
}
|
|
51914
|
+
callOptions = { ...callOptions, messages: msgs };
|
|
51915
|
+
}
|
|
51916
|
+
return super.call(callOptions);
|
|
51917
|
+
}
|
|
51918
|
+
modifyRequestBody(body, options) {
|
|
51919
|
+
if (this._isGemma4(this._currentModelId)) {
|
|
51920
|
+
const enableThinking = options.thinking?.enabled !== false;
|
|
51921
|
+
body.extra_body = {
|
|
51922
|
+
...body.extra_body ?? {},
|
|
51923
|
+
chat_template_kwargs: { enable_thinking: enableThinking }
|
|
51924
|
+
};
|
|
51925
|
+
}
|
|
51926
|
+
return body;
|
|
51927
|
+
}
|
|
51928
|
+
async _ensureModelLoaded(modelId, options) {
|
|
51929
|
+
const status = await getHiveAgentsModelStatus(options.apiKey, options.baseUrl);
|
|
51930
|
+
if (status.loaded && status.model?.name === modelId) {
|
|
51931
|
+
log29.info(`[hiveagents] Model ${modelId} already loaded`);
|
|
51932
|
+
return;
|
|
51933
|
+
}
|
|
51934
|
+
log29.warn(`[hiveagents] Model ${modelId} not loaded. Triggering load with ctx=${HIVEAGENTS_DEFAULT_LOAD_CTX}`);
|
|
51935
|
+
const result = await loadHiveAgentsModel(modelId, options.apiKey, options.baseUrl);
|
|
51936
|
+
if (!result.success) {
|
|
51937
|
+
log29.warn(`[hiveagents] Auto-load failed for ${modelId}: ${result.error}`);
|
|
51938
|
+
}
|
|
51939
|
+
}
|
|
51940
|
+
injectToolsIntoPrompt(body, preparedTools) {
|
|
51941
|
+
if (body.tools && body.tools.length > 0) {
|
|
51942
|
+
return;
|
|
51943
|
+
}
|
|
51944
|
+
const toolDescriptions = preparedTools.map((t) => JSON.stringify(t.function)).join(`
|
|
51945
|
+
`);
|
|
51946
|
+
const instruction = [
|
|
51947
|
+
"You have access to the following tools.",
|
|
51948
|
+
"When you need to use a tool, output EXACTLY one JSON block wrapped in <tool_call> tags and NOTHING ELSE in that turn:",
|
|
51949
|
+
"",
|
|
51950
|
+
"<tool_call>",
|
|
51951
|
+
'{"name": "browser_navigate", "arguments": {"url": "https://example.com"}}',
|
|
51952
|
+
"</tool_call>",
|
|
51953
|
+
"",
|
|
51954
|
+
"Use the exact tool name and argument names from the list below. Do not add extra text, markdown, or explanations inside the tool_call block.",
|
|
51955
|
+
"",
|
|
51956
|
+
"Tools:",
|
|
51957
|
+
toolDescriptions
|
|
51958
|
+
].join(`
|
|
51959
|
+
`);
|
|
51960
|
+
const sysMsg = body.messages.find((m2) => m2.role === "system");
|
|
51961
|
+
if (sysMsg) {
|
|
51962
|
+
sysMsg.content += `
|
|
51963
|
+
|
|
51964
|
+
` + instruction;
|
|
51965
|
+
} else {
|
|
51966
|
+
body.messages.unshift({ role: "system", content: instruction });
|
|
51967
|
+
}
|
|
51968
|
+
}
|
|
51969
|
+
};
|
|
51970
|
+
});
|
|
51971
|
+
|
|
51756
51972
|
// packages/core/src/storage/crypto.ts
|
|
51757
51973
|
var exports_crypto = {};
|
|
51758
51974
|
__export(exports_crypto, {
|
|
@@ -52045,7 +52261,7 @@ function persistSecretToDb(name, value) {
|
|
|
52045
52261
|
}
|
|
52046
52262
|
const key = getMasterKey();
|
|
52047
52263
|
if (!key) {
|
|
52048
|
-
|
|
52264
|
+
log30.warn(`[secrets] No master key in ${process.env.HIVE_HOME || "~/.hive"}/.master.key \u2014 cannot persist ${name} to DB fallback`);
|
|
52049
52265
|
return false;
|
|
52050
52266
|
}
|
|
52051
52267
|
const iv = nodeCrypto.randomBytes(12).toString("hex");
|
|
@@ -52057,15 +52273,15 @@ function persistSecretToDb(name, value) {
|
|
|
52057
52273
|
db.query(`UPDATE ${table} SET ${column}_encrypted = ?, ${column}_iv = ? WHERE id = ?`).run(enc, iv, id);
|
|
52058
52274
|
return true;
|
|
52059
52275
|
} catch (err) {
|
|
52060
|
-
|
|
52276
|
+
log30.warn(`[secrets] DB fallback failed for ${name}: ${err.message}`);
|
|
52061
52277
|
return false;
|
|
52062
52278
|
}
|
|
52063
52279
|
}
|
|
52064
|
-
var
|
|
52280
|
+
var log30, SERVICE = "hive", _mem, _keychainOk = null;
|
|
52065
52281
|
var init_crypto = __esm(() => {
|
|
52066
52282
|
init_logger();
|
|
52067
52283
|
init_sqlite();
|
|
52068
|
-
|
|
52284
|
+
log30 = logger.child("crypto");
|
|
52069
52285
|
_mem = new Map;
|
|
52070
52286
|
});
|
|
52071
52287
|
|
|
@@ -52101,8 +52317,10 @@ function getProvider(provider) {
|
|
|
52101
52317
|
return new MiniMaxProvider;
|
|
52102
52318
|
case "opencode-go":
|
|
52103
52319
|
return new OpenCodeGoProvider;
|
|
52320
|
+
case "hiveagents":
|
|
52321
|
+
return new HiveAgentsProvider;
|
|
52104
52322
|
default:
|
|
52105
|
-
|
|
52323
|
+
log31.warn(`[llm-client] Unknown provider "${provider}" \u2014 falling back to OpenAI-compatible endpoint`);
|
|
52106
52324
|
return new OpenAIProvider;
|
|
52107
52325
|
}
|
|
52108
52326
|
}
|
|
@@ -52112,7 +52330,7 @@ async function callLLM(options) {
|
|
|
52112
52330
|
} catch (err) {
|
|
52113
52331
|
const msg = err.message;
|
|
52114
52332
|
const cleanModel = options.model.replace(new RegExp(`^${options.provider}\\/`), "");
|
|
52115
|
-
|
|
52333
|
+
log31.error(`[llm-client] Error calling ${options.provider}/${cleanModel}: ${msg}`, err);
|
|
52116
52334
|
return { content: `[LLM Error] ${msg}`, stop_reason: "error" };
|
|
52117
52335
|
}
|
|
52118
52336
|
}
|
|
@@ -52136,7 +52354,7 @@ async function resolveProviderConfig(providerId, modelId) {
|
|
|
52136
52354
|
contextWindow: modelRow?.context_window ?? undefined
|
|
52137
52355
|
};
|
|
52138
52356
|
}
|
|
52139
|
-
var
|
|
52357
|
+
var log31;
|
|
52140
52358
|
var init_llm_client = __esm(() => {
|
|
52141
52359
|
init_logger();
|
|
52142
52360
|
init_gemini();
|
|
@@ -52153,7 +52371,8 @@ var init_llm_client = __esm(() => {
|
|
|
52153
52371
|
init_qwen();
|
|
52154
52372
|
init_minimax();
|
|
52155
52373
|
init_opencode_go();
|
|
52156
|
-
|
|
52374
|
+
init_hiveagents();
|
|
52375
|
+
log31 = logger.child("llm-client");
|
|
52157
52376
|
});
|
|
52158
52377
|
|
|
52159
52378
|
// node_modules/.bun/toon-format-parser@1.1.4/node_modules/toon-format-parser/dist/index.mjs
|
|
@@ -52616,13 +52835,13 @@ function recordUsage(options) {
|
|
|
52616
52835
|
INSERT INTO usage_records (id, provider, model, input_tokens, output_tokens, cost_usd, latency_ms, created_at)
|
|
52617
52836
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
52618
52837
|
`).run(randomUUID(), options.provider, options.model, options.inputTokens, options.outputTokens, costUsd, options.latencyMs || null, Math.floor(Date.now() / 1000));
|
|
52619
|
-
|
|
52838
|
+
log32.info(`[USAGE RECORDED] provider=${options.provider} model=${options.model} input=${options.inputTokens} output=${options.outputTokens} cost=$${costUsd.toFixed(4)}`);
|
|
52620
52839
|
} catch (error4) {
|
|
52621
52840
|
console.error("Failed to record usage:", error4);
|
|
52622
52841
|
}
|
|
52623
52842
|
}
|
|
52624
52843
|
function getUsageStats(hours = 24) {
|
|
52625
|
-
|
|
52844
|
+
log32.info(`[USAGE STATS] Fetching stats for last ${hours} hours`);
|
|
52626
52845
|
const db = getDb();
|
|
52627
52846
|
const since = Math.floor(Date.now() / 1000) - hours * 3600;
|
|
52628
52847
|
const totals = db.prepare(`
|
|
@@ -52748,17 +52967,17 @@ function recordToonSavings(analysis, costSaved, category) {
|
|
|
52748
52967
|
)
|
|
52749
52968
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
52750
52969
|
`).run(`toon_${category}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`, "toon", category, 0, 0, 0, Math.max(0, analysis.savedTokens), costSaved, analysis.jsonBytes, analysis.toonBytes, analysis.savedBytes, Math.max(0, analysis.savedPercent), analysis.jsonTokens, analysis.toonTokens, Math.max(0, analysis.savedTokensPercent), Math.floor(Date.now() / 1000));
|
|
52751
|
-
|
|
52970
|
+
log32.debug(`[TOON] Recorded ${analysis.savedTokens} tokens ($${costSaved.toFixed(6)}) saved for ${category}`);
|
|
52752
52971
|
} catch (error4) {
|
|
52753
|
-
|
|
52972
|
+
log32.warn(`[TOON] Failed to record savings:`, error4);
|
|
52754
52973
|
}
|
|
52755
52974
|
});
|
|
52756
52975
|
}
|
|
52757
|
-
var
|
|
52976
|
+
var log32, MODEL_PRICING;
|
|
52758
52977
|
var init_usage2 = __esm(() => {
|
|
52759
52978
|
init_sqlite();
|
|
52760
52979
|
init_logger();
|
|
52761
|
-
|
|
52980
|
+
log32 = logger.child("usage");
|
|
52762
52981
|
MODEL_PRICING = {
|
|
52763
52982
|
"claude-opus-4-6": { inputPer1M: 5, outputPer1M: 25 },
|
|
52764
52983
|
"claude-sonnet-4-6": { inputPer1M: 3, outputPer1M: 15 },
|
|
@@ -52840,7 +53059,7 @@ function stringify2(data, model) {
|
|
|
52840
53059
|
const tokensSaved = Math.max(0, analysis.savedTokens);
|
|
52841
53060
|
const savingsPercent = Math.max(0, analysis.savedTokensPercent);
|
|
52842
53061
|
const costSaved = tokensSaved * TOON_AVERAGE_COST_PER_TOKEN;
|
|
52843
|
-
|
|
53062
|
+
log33.debug(`[TOON] Converted - saved ${tokensSaved} tokens ($${costSaved.toFixed(6)}) (${savingsPercent.toFixed(1)}%)`);
|
|
52844
53063
|
return {
|
|
52845
53064
|
content: toonContent,
|
|
52846
53065
|
format: "toon",
|
|
@@ -52858,7 +53077,7 @@ function stringify2(data, model) {
|
|
|
52858
53077
|
savedTokensPercent: analysis.savedTokensPercent
|
|
52859
53078
|
};
|
|
52860
53079
|
} catch (error4) {
|
|
52861
|
-
|
|
53080
|
+
log33.warn(`[TOON] Failed, falling back to JSON:`, error4);
|
|
52862
53081
|
return {
|
|
52863
53082
|
content: jsonContent,
|
|
52864
53083
|
format: "toon",
|
|
@@ -52909,12 +53128,12 @@ function formatContext(data, model) {
|
|
|
52909
53128
|
}
|
|
52910
53129
|
return result.content;
|
|
52911
53130
|
}
|
|
52912
|
-
var
|
|
53131
|
+
var log33, TOON_AVERAGE_COST_PER_TOKEN = 0.000000375;
|
|
52913
53132
|
var init_toon = __esm(() => {
|
|
52914
53133
|
init_dist2();
|
|
52915
53134
|
init_logger();
|
|
52916
53135
|
init_usage2();
|
|
52917
|
-
|
|
53136
|
+
log33 = logger.child("toon");
|
|
52918
53137
|
});
|
|
52919
53138
|
|
|
52920
53139
|
// packages/core/src/agent/conversation-store.ts
|
|
@@ -52966,7 +53185,7 @@ function stripLeadingOrphanedTools(rows) {
|
|
|
52966
53185
|
start++;
|
|
52967
53186
|
}
|
|
52968
53187
|
if (start > 0) {
|
|
52969
|
-
|
|
53188
|
+
log34.warn(`[conv-store] Stripped ${start} leading orphaned tool message(s) from window (tool_call_ids outside window)`);
|
|
52970
53189
|
}
|
|
52971
53190
|
return start > 0 ? rows.slice(start) : rows;
|
|
52972
53191
|
}
|
|
@@ -53014,12 +53233,12 @@ function getScratchpad(threadId) {
|
|
|
53014
53233
|
const db = getDb();
|
|
53015
53234
|
return db.query("SELECT key, value FROM scratchpad WHERE thread_id = ? ORDER BY updated_at DESC").all(threadId);
|
|
53016
53235
|
}
|
|
53017
|
-
var
|
|
53236
|
+
var log34;
|
|
53018
53237
|
var init_conversation_store = __esm(() => {
|
|
53019
53238
|
init_sqlite();
|
|
53020
53239
|
init_logger();
|
|
53021
53240
|
init_toon();
|
|
53022
|
-
|
|
53241
|
+
log34 = logger.child("conv-store");
|
|
53023
53242
|
});
|
|
53024
53243
|
|
|
53025
53244
|
// packages/core/src/agent/curator.ts
|
|
@@ -53034,9 +53253,9 @@ async function runCurator() {
|
|
|
53034
53253
|
const lastProcessed = db.query("SELECT COALESCE(MAX(source_reflection_id), 0) as mid FROM playbook").get()?.mid ?? 0;
|
|
53035
53254
|
const reflections = db.query("SELECT * FROM reflections WHERE id > ? ORDER BY id ASC").all(lastProcessed);
|
|
53036
53255
|
if (reflections.length === 0) {
|
|
53037
|
-
|
|
53256
|
+
log35.debug("[curator] No new reflections to process");
|
|
53038
53257
|
} else {
|
|
53039
|
-
|
|
53258
|
+
log35.info(`[curator] Processing ${reflections.length} new reflections`);
|
|
53040
53259
|
for (const reflection of reflections) {
|
|
53041
53260
|
processReflection(db, reflection);
|
|
53042
53261
|
}
|
|
@@ -53067,11 +53286,11 @@ async function runCurator() {
|
|
|
53067
53286
|
applicable_to: null,
|
|
53068
53287
|
sourceReflectionId: null
|
|
53069
53288
|
});
|
|
53070
|
-
|
|
53289
|
+
log35.info(`[curator] Archived inactive worker: ${worker.name} (${worker.id})`);
|
|
53071
53290
|
}
|
|
53072
|
-
|
|
53291
|
+
log35.info("[curator] Playbook updated");
|
|
53073
53292
|
} catch (err) {
|
|
53074
|
-
|
|
53293
|
+
log35.warn("[curator] Error:", err);
|
|
53075
53294
|
}
|
|
53076
53295
|
}
|
|
53077
53296
|
function processReflection(db, reflection) {
|
|
@@ -53108,10 +53327,10 @@ function addOrUpdateRule(db, opts) {
|
|
|
53108
53327
|
`).run(opts.rule, opts.category, opts.applicable_to, opts.sourceReflectionId);
|
|
53109
53328
|
}
|
|
53110
53329
|
}
|
|
53111
|
-
var
|
|
53330
|
+
var log35, DAYS_BEFORE_ARCHIVE = 14, MAX_HARMFUL_BEFORE_PRUNE = 3;
|
|
53112
53331
|
var init_curator = __esm(() => {
|
|
53113
53332
|
init_logger();
|
|
53114
|
-
|
|
53333
|
+
log35 = logger.child("curator");
|
|
53115
53334
|
});
|
|
53116
53335
|
|
|
53117
53336
|
// packages/core/src/agent/reflector.ts
|
|
@@ -53123,21 +53342,21 @@ async function runReflector() {
|
|
|
53123
53342
|
try {
|
|
53124
53343
|
const { getDb: getDb2 } = await Promise.resolve().then(() => (init_sqlite(), exports_sqlite));
|
|
53125
53344
|
const db = getDb2();
|
|
53126
|
-
|
|
53127
|
-
|
|
53345
|
+
log36.info(`[reflector] Starting reflection cycle...`);
|
|
53346
|
+
log36.debug(`[reflector] Querying last reflection ID...`);
|
|
53128
53347
|
const lastReflectionId = db.query("SELECT MAX(id) as mid FROM reflections").get()?.mid ?? 0;
|
|
53129
|
-
|
|
53130
|
-
|
|
53348
|
+
log36.debug(`[reflector] Last reflection ID: ${lastReflectionId}`);
|
|
53349
|
+
log36.debug(`[reflector] Querying last processed trace ID with json_each...`);
|
|
53131
53350
|
let lastProcessedTrace = 0;
|
|
53132
53351
|
try {
|
|
53133
53352
|
const result = db.query(`SELECT MAX(CAST(json_each.value AS INTEGER)) as max_id
|
|
53134
53353
|
FROM reflections, json_each(reflections.trace_ids)
|
|
53135
53354
|
WHERE reflections.id = (SELECT MAX(id) FROM reflections)`).get()?.max_id ?? 0;
|
|
53136
53355
|
lastProcessedTrace = result;
|
|
53137
|
-
|
|
53356
|
+
log36.debug(`[reflector] Last processed trace ID: ${lastProcessedTrace}`);
|
|
53138
53357
|
} catch (jsonErr) {
|
|
53139
|
-
|
|
53140
|
-
|
|
53358
|
+
log36.error(`[reflector] json_each query failed:`, jsonErr);
|
|
53359
|
+
log36.error(`[reflector] Full error details:`, {
|
|
53141
53360
|
message: jsonErr.message,
|
|
53142
53361
|
stack: jsonErr.stack,
|
|
53143
53362
|
errno: jsonErr.errno,
|
|
@@ -53145,7 +53364,7 @@ async function runReflector() {
|
|
|
53145
53364
|
});
|
|
53146
53365
|
throw jsonErr;
|
|
53147
53366
|
}
|
|
53148
|
-
|
|
53367
|
+
log36.debug(`[reflector] Fetching traces from DB, lastProcessedTrace=${lastProcessedTrace}, limit=${MAX_TRACES_TO_ANALYZE}`);
|
|
53149
53368
|
const traces = db.query(`
|
|
53150
53369
|
SELECT id, agent_id, agent_name, tool_used, input_summary,
|
|
53151
53370
|
output_summary, success, error_message, duration_ms, tokens_used, created_at
|
|
@@ -53154,15 +53373,15 @@ async function runReflector() {
|
|
|
53154
53373
|
ORDER BY id ASC
|
|
53155
53374
|
LIMIT ?
|
|
53156
53375
|
`).all(lastProcessedTrace, MAX_TRACES_TO_ANALYZE);
|
|
53157
|
-
|
|
53376
|
+
log36.debug(`[reflector] Fetched ${traces.length} traces from DB`);
|
|
53158
53377
|
if (traces.length < MIN_TRACES_TO_RUN) {
|
|
53159
|
-
|
|
53378
|
+
log36.debug(`[reflector] Not enough traces (${traces.length}/${MIN_TRACES_TO_RUN}), skipping`);
|
|
53160
53379
|
return;
|
|
53161
53380
|
}
|
|
53162
|
-
|
|
53381
|
+
log36.info(`[reflector] Analyzing ${traces.length} traces...`);
|
|
53163
53382
|
const insights = analyzeTracesLocally(traces);
|
|
53164
53383
|
if (insights.length === 0) {
|
|
53165
|
-
|
|
53384
|
+
log36.debug("[reflector] No insights generated");
|
|
53166
53385
|
return;
|
|
53167
53386
|
}
|
|
53168
53387
|
const traceIds = JSON.stringify(traces.map((t) => t.id));
|
|
@@ -53172,12 +53391,12 @@ async function runReflector() {
|
|
|
53172
53391
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
53173
53392
|
`).run(traceIds, insight.type, insight.description, insight.affectedTools ? JSON.stringify(insight.affectedTools) : null, insight.affectedAgents ? JSON.stringify(insight.affectedAgents) : null, insight.confidence);
|
|
53174
53393
|
}
|
|
53175
|
-
|
|
53394
|
+
log36.info(`[reflector] Generated ${insights.length} insights`);
|
|
53176
53395
|
const { runCurator: runCurator2 } = await Promise.resolve().then(() => (init_curator(), exports_curator));
|
|
53177
53396
|
await runCurator2();
|
|
53178
|
-
|
|
53397
|
+
log36.info(`[reflector] Reflection cycle completed successfully`);
|
|
53179
53398
|
} catch (err) {
|
|
53180
|
-
|
|
53399
|
+
log36.error(`[reflector] Error during reflection:`, {
|
|
53181
53400
|
message: err.message,
|
|
53182
53401
|
stack: err.stack,
|
|
53183
53402
|
errno: err.errno,
|
|
@@ -53257,10 +53476,10 @@ function analyzeTracesLocally(traces) {
|
|
|
53257
53476
|
}
|
|
53258
53477
|
return insights;
|
|
53259
53478
|
}
|
|
53260
|
-
var
|
|
53479
|
+
var log36, MAX_TRACES_TO_ANALYZE = 30, MIN_TRACES_TO_RUN = 10;
|
|
53261
53480
|
var init_reflector = __esm(() => {
|
|
53262
53481
|
init_logger();
|
|
53263
|
-
|
|
53482
|
+
log36 = logger.child("reflector");
|
|
53264
53483
|
});
|
|
53265
53484
|
|
|
53266
53485
|
// packages/core/src/agent/tracer.ts
|
|
@@ -53277,7 +53496,7 @@ function saveTrace(trace) {
|
|
|
53277
53496
|
`).run(trace.threadId, trace.agentId, trace.agentName, trace.toolUsed ?? null, trace.inputSummary.substring(0, 500), trace.outputSummary.substring(0, 500), trace.success ? 1 : 0, trace.errorMessage ?? null, trace.durationMs ?? null, trace.tokensUsed ?? null);
|
|
53278
53497
|
checkReflectorTrigger().catch(() => {});
|
|
53279
53498
|
} catch (err) {
|
|
53280
|
-
|
|
53499
|
+
log37.warn("[tracer] Failed to save trace:", err);
|
|
53281
53500
|
}
|
|
53282
53501
|
});
|
|
53283
53502
|
}
|
|
@@ -53288,7 +53507,7 @@ async function checkReflectorTrigger() {
|
|
|
53288
53507
|
_tracesSinceLastReflection = 0;
|
|
53289
53508
|
const { runReflector: runReflector2 } = await Promise.resolve().then(() => (init_reflector(), exports_reflector));
|
|
53290
53509
|
runReflector2().catch((err) => {
|
|
53291
|
-
|
|
53510
|
+
log37.warn("[tracer] Reflector run failed:", err);
|
|
53292
53511
|
});
|
|
53293
53512
|
}
|
|
53294
53513
|
function recordLLMUsage(opts) {
|
|
@@ -53304,10 +53523,10 @@ function recordLLMUsage(opts) {
|
|
|
53304
53523
|
} catch {}
|
|
53305
53524
|
});
|
|
53306
53525
|
}
|
|
53307
|
-
var
|
|
53526
|
+
var log37, REFLECTOR_TRACE_THRESHOLD = 20, _tracesSinceLastReflection = 0;
|
|
53308
53527
|
var init_tracer = __esm(() => {
|
|
53309
53528
|
init_logger();
|
|
53310
|
-
|
|
53529
|
+
log37 = logger.child("tracer");
|
|
53311
53530
|
});
|
|
53312
53531
|
|
|
53313
53532
|
// packages/core/src/gateway/channel-notify.ts
|
|
@@ -53318,7 +53537,7 @@ __export(exports_channel_notify, {
|
|
|
53318
53537
|
});
|
|
53319
53538
|
function setChannelSendFn(fn) {
|
|
53320
53539
|
_sendFn = fn;
|
|
53321
|
-
|
|
53540
|
+
log38.info("[channel-notify] Send function registered");
|
|
53322
53541
|
}
|
|
53323
53542
|
function resolveSessionId(userId, channel) {
|
|
53324
53543
|
try {
|
|
@@ -53331,24 +53550,24 @@ function resolveSessionId(userId, channel) {
|
|
|
53331
53550
|
}
|
|
53332
53551
|
async function sendToUserChannel(channel, userId, message) {
|
|
53333
53552
|
if (!_sendFn) {
|
|
53334
|
-
|
|
53553
|
+
log38.warn("[channel-notify] No send function registered \u2014 message dropped");
|
|
53335
53554
|
return { ok: false, error: "Channel send not initialized" };
|
|
53336
53555
|
}
|
|
53337
53556
|
const sessionId = resolveSessionId(userId, channel);
|
|
53338
|
-
|
|
53557
|
+
log38.info(`[channel-notify] Sending to ${channel}/${sessionId}: ${message.substring(0, 80)}`);
|
|
53339
53558
|
try {
|
|
53340
53559
|
await _sendFn(channel, sessionId, message);
|
|
53341
53560
|
return { ok: true };
|
|
53342
53561
|
} catch (err) {
|
|
53343
|
-
|
|
53562
|
+
log38.warn(`[channel-notify] Failed to send: ${err.message}`);
|
|
53344
53563
|
return { ok: false, error: err.message };
|
|
53345
53564
|
}
|
|
53346
53565
|
}
|
|
53347
|
-
var
|
|
53566
|
+
var log38, _sendFn = null;
|
|
53348
53567
|
var init_channel_notify = __esm(() => {
|
|
53349
53568
|
init_logger();
|
|
53350
53569
|
init_sqlite();
|
|
53351
|
-
|
|
53570
|
+
log38 = logger.child("channel-notify");
|
|
53352
53571
|
});
|
|
53353
53572
|
|
|
53354
53573
|
// packages/core/src/agent/compaction.ts
|
|
@@ -53372,10 +53591,10 @@ async function maybeCompact(threadId, notify) {
|
|
|
53372
53591
|
const totalMessages = getMessageCount(threadId);
|
|
53373
53592
|
if (summary && summary.last_message_id > totalMessages - KEEP_LAST_N_MESSAGES)
|
|
53374
53593
|
return;
|
|
53375
|
-
|
|
53594
|
+
log39.info(`[compaction] Compacting thread=${threadId} tokens=${totalTokens}`);
|
|
53376
53595
|
await compactThread(threadId, notify);
|
|
53377
53596
|
} catch (err) {
|
|
53378
|
-
|
|
53597
|
+
log39.warn("[compaction] Error during compaction check:", err);
|
|
53379
53598
|
}
|
|
53380
53599
|
}
|
|
53381
53600
|
async function compactThread(threadId, notify) {
|
|
@@ -53387,7 +53606,7 @@ async function compactThread(threadId, notify) {
|
|
|
53387
53606
|
cutIndex--;
|
|
53388
53607
|
}
|
|
53389
53608
|
if (cutIndex <= 0) {
|
|
53390
|
-
|
|
53609
|
+
log39.info(`[compaction] No clean user-turn boundary found \u2014 skipping`);
|
|
53391
53610
|
return;
|
|
53392
53611
|
}
|
|
53393
53612
|
const toSummarize = allMessages.slice(0, cutIndex);
|
|
@@ -53428,7 +53647,7 @@ ${transcript}`
|
|
|
53428
53647
|
if (!summary)
|
|
53429
53648
|
return;
|
|
53430
53649
|
saveSummary(threadId, summary, toSummarize.length, lastSummarizedId);
|
|
53431
|
-
|
|
53650
|
+
log39.info(`[compaction] Thread ${threadId} compacted: ${toSummarize.length} msgs \u2192 ${estimateTokens(summary)} tokens`);
|
|
53432
53651
|
if (notify?.channel && notify?.userId) {
|
|
53433
53652
|
try {
|
|
53434
53653
|
const { sendToUserChannel: sendToUserChannel2 } = await Promise.resolve().then(() => (init_channel_notify(), exports_channel_notify));
|
|
@@ -53460,14 +53679,14 @@ function clearOldToolResults(messages, keepLastN = 6) {
|
|
|
53460
53679
|
return msg;
|
|
53461
53680
|
});
|
|
53462
53681
|
}
|
|
53463
|
-
var
|
|
53682
|
+
var log39, COMPACT_TOKEN_THRESHOLD = 32000, KEEP_LAST_N_MESSAGES = 5, TOOL_RESULT_MAX_CHARS = 200, MAX_TRANSCRIPT_MSGS = 30, MAX_MSG_CHARS = 300;
|
|
53464
53683
|
var init_compaction = __esm(() => {
|
|
53465
53684
|
init_logger();
|
|
53466
53685
|
init_conversation_store();
|
|
53467
53686
|
init_toon();
|
|
53468
53687
|
init_llm_client();
|
|
53469
53688
|
init_sqlite();
|
|
53470
|
-
|
|
53689
|
+
log39 = logger.child("compaction");
|
|
53471
53690
|
});
|
|
53472
53691
|
|
|
53473
53692
|
// packages/core/src/canvas/emitter.ts
|
|
@@ -53513,11 +53732,11 @@ function mcpToolFullName(serverName, toolName) {
|
|
|
53513
53732
|
const trimmed = full.length > 64 ? full.substring(0, 64) : full;
|
|
53514
53733
|
return /^[a-zA-Z_]/.test(trimmed) ? trimmed : `_${trimmed}`.substring(0, 64);
|
|
53515
53734
|
}
|
|
53516
|
-
var
|
|
53735
|
+
var log40, STOPWORDS;
|
|
53517
53736
|
var init_tool_selector = __esm(() => {
|
|
53518
53737
|
init_sqlite();
|
|
53519
53738
|
init_logger();
|
|
53520
|
-
|
|
53739
|
+
log40 = logger.child("tool-selector");
|
|
53521
53740
|
STOPWORDS = new Set([
|
|
53522
53741
|
"que",
|
|
53523
53742
|
"con",
|
|
@@ -53587,14 +53806,14 @@ function isConversational(message) {
|
|
|
53587
53806
|
return true;
|
|
53588
53807
|
for (const pattern of CONVERSATIONAL_PATTERNS) {
|
|
53589
53808
|
if (pattern.test(trimmed)) {
|
|
53590
|
-
|
|
53809
|
+
log41.debug(`[skill-selector] Message matched conversational pattern: ${pattern}`);
|
|
53591
53810
|
return true;
|
|
53592
53811
|
}
|
|
53593
53812
|
}
|
|
53594
53813
|
const words = trimmed.toLowerCase().split(/\s+/);
|
|
53595
53814
|
const meaningfulWords = words.filter((w2) => w2.length > 2 && !STOPWORDS2.has(w2));
|
|
53596
53815
|
if (meaningfulWords.length === 0) {
|
|
53597
|
-
|
|
53816
|
+
log41.debug(`[skill-selector] All words are stopwords - conversational`);
|
|
53598
53817
|
return true;
|
|
53599
53818
|
}
|
|
53600
53819
|
return false;
|
|
@@ -53615,15 +53834,15 @@ function matchTriggers(message, triggersJson) {
|
|
|
53615
53834
|
const lowerMessage = message.toLowerCase();
|
|
53616
53835
|
return triggers.some((trigger) => lowerMessage.includes(trigger.toLowerCase()));
|
|
53617
53836
|
} catch (err) {
|
|
53618
|
-
|
|
53837
|
+
log41.warn(`[skill-selector] Failed to parse triggers: ${err.message}`);
|
|
53619
53838
|
return false;
|
|
53620
53839
|
}
|
|
53621
53840
|
}
|
|
53622
53841
|
function selectSkills(userMessage) {
|
|
53623
53842
|
const startTime = performance.now();
|
|
53624
|
-
|
|
53843
|
+
log41.debug(`[skill-selector] Processing user message: "${userMessage.substring(0, 100)}"`);
|
|
53625
53844
|
if (isConversational(userMessage)) {
|
|
53626
|
-
|
|
53845
|
+
log41.debug(`[skill-selector] Conversational message, returning empty array`);
|
|
53627
53846
|
return [];
|
|
53628
53847
|
}
|
|
53629
53848
|
const db = getDb();
|
|
@@ -53634,16 +53853,16 @@ function selectSkills(userMessage) {
|
|
|
53634
53853
|
`).all();
|
|
53635
53854
|
for (const skill of allSkills) {
|
|
53636
53855
|
if (skill.triggers && matchTriggers(userMessage, skill.triggers)) {
|
|
53637
|
-
|
|
53856
|
+
log41.info(`[skill-selector] Trigger match found: ${skill.name}`);
|
|
53638
53857
|
return [skill];
|
|
53639
53858
|
}
|
|
53640
53859
|
}
|
|
53641
53860
|
const ftsQuery = buildFTSQuery(userMessage);
|
|
53642
53861
|
if (!ftsQuery) {
|
|
53643
|
-
|
|
53862
|
+
log41.debug(`[skill-selector] No valid FTS query terms, returning empty array`);
|
|
53644
53863
|
return [];
|
|
53645
53864
|
}
|
|
53646
|
-
|
|
53865
|
+
log41.debug(`[skill-selector] FTS query: "${ftsQuery}"`);
|
|
53647
53866
|
const ftsResults = db.query(`
|
|
53648
53867
|
SELECT id, bm25(skills_fts, 1.0, 4.0, 5.0, 1.0, 1.0, 5.0, 2.0) as bm25_score
|
|
53649
53868
|
FROM skills_fts
|
|
@@ -53652,13 +53871,13 @@ function selectSkills(userMessage) {
|
|
|
53652
53871
|
LIMIT 20
|
|
53653
53872
|
`).all(ftsQuery);
|
|
53654
53873
|
if (ftsResults.length === 0) {
|
|
53655
|
-
|
|
53874
|
+
log41.debug(`[skill-selector] No FTS matches, returning empty array`);
|
|
53656
53875
|
return [];
|
|
53657
53876
|
}
|
|
53658
|
-
|
|
53877
|
+
log41.info(`[skill-selector] Raw FTS scores: ${ftsResults.slice(0, 10).map((r) => `id=${r.id}, score=${r.bm25_score.toFixed(2)}`).join(", ")}`);
|
|
53659
53878
|
const relevantResults = ftsResults.filter((r) => r.bm25_score >= MIN_RELEVANCE_THRESHOLD);
|
|
53660
53879
|
if (relevantResults.length === 0) {
|
|
53661
|
-
|
|
53880
|
+
log41.debug(`[skill-selector] All results below threshold ${MIN_RELEVANCE_THRESHOLD}, returning empty`);
|
|
53662
53881
|
return [];
|
|
53663
53882
|
}
|
|
53664
53883
|
const skillIds = relevantResults.map((r) => r.id);
|
|
@@ -53672,7 +53891,7 @@ function selectSkills(userMessage) {
|
|
|
53672
53891
|
AND active = 1
|
|
53673
53892
|
`).all(...skillIds);
|
|
53674
53893
|
} catch (err) {
|
|
53675
|
-
|
|
53894
|
+
log41.warn(`[skill-selector] Failed to fetch skills from DB:`, err);
|
|
53676
53895
|
return [];
|
|
53677
53896
|
}
|
|
53678
53897
|
const skillMap = new Map(dbSkills.map((s2) => [s2.id, s2]));
|
|
@@ -53694,9 +53913,9 @@ function selectSkills(userMessage) {
|
|
|
53694
53913
|
const result = topSkills.map((t) => skillMap.get(t.id)).filter(Boolean);
|
|
53695
53914
|
const timing = performance.now() - startTime;
|
|
53696
53915
|
if (result.length > 0) {
|
|
53697
|
-
|
|
53916
|
+
log41.info(`[skill-selector] Selected ${result.length} skills in ${timing.toFixed(2)}ms:`, result.map((s2) => ({ name: s2.name, category: s2.category })));
|
|
53698
53917
|
} else {
|
|
53699
|
-
|
|
53918
|
+
log41.debug(`[skill-selector] No skills selected, returning empty array in ${timing.toFixed(2)}ms`);
|
|
53700
53919
|
}
|
|
53701
53920
|
return result;
|
|
53702
53921
|
}
|
|
@@ -53710,18 +53929,18 @@ function getMinimalSkills() {
|
|
|
53710
53929
|
WHERE name IN (${placeholders})
|
|
53711
53930
|
AND active = 1
|
|
53712
53931
|
`).all(...MINIMAL_SKILL_NAMES);
|
|
53713
|
-
|
|
53932
|
+
log41.info(`[skill-selector] Loaded ${skills.length} minimal skills: ${skills.map((s2) => s2.name).join(", ")}`);
|
|
53714
53933
|
return skills;
|
|
53715
53934
|
} catch (err) {
|
|
53716
|
-
|
|
53935
|
+
log41.error(`[skill-selector] Failed to load minimal skills:`, err);
|
|
53717
53936
|
return [];
|
|
53718
53937
|
}
|
|
53719
53938
|
}
|
|
53720
|
-
var
|
|
53939
|
+
var log41, MINIMAL_SKILL_NAMES, MAX_SKILLS_PER_TURN = 4, MIN_RELEVANCE_THRESHOLD = -15, STOPWORDS2, CONVERSATIONAL_PATTERNS;
|
|
53721
53940
|
var init_skill_selector = __esm(() => {
|
|
53722
53941
|
init_sqlite();
|
|
53723
53942
|
init_logger();
|
|
53724
|
-
|
|
53943
|
+
log41 = logger.child("skill-selector");
|
|
53725
53944
|
MINIMAL_SKILL_NAMES = new Set([
|
|
53726
53945
|
"busqueda_fts5",
|
|
53727
53946
|
"memory_manager",
|
|
@@ -53807,11 +54026,11 @@ var init_skill_selector = __esm(() => {
|
|
|
53807
54026
|
});
|
|
53808
54027
|
|
|
53809
54028
|
// packages/core/src/agent/playbook-selector.ts
|
|
53810
|
-
var
|
|
54029
|
+
var log42;
|
|
53811
54030
|
var init_playbook_selector = __esm(() => {
|
|
53812
54031
|
init_sqlite();
|
|
53813
54032
|
init_logger();
|
|
53814
|
-
|
|
54033
|
+
log42 = logger.child("playbook-selector");
|
|
53815
54034
|
});
|
|
53816
54035
|
|
|
53817
54036
|
// packages/skills/src/bundled-data.generated.ts
|
|
@@ -53822,6 +54041,544 @@ __export(exports_bundled_data_generated, {
|
|
|
53822
54041
|
var BUNDLED_SKILLS_DATA;
|
|
53823
54042
|
var init_bundled_data_generated = __esm(() => {
|
|
53824
54043
|
BUNDLED_SKILLS_DATA = [
|
|
54044
|
+
{
|
|
54045
|
+
name: "cron_manager",
|
|
54046
|
+
description: `Complete management of cron jobs with cron expressions. Create, list, update, pause, resume, delete, trigger, and view history. Use for reminders, automated reports, periodic checks.`,
|
|
54047
|
+
category: "cron",
|
|
54048
|
+
version: "2.0.0",
|
|
54049
|
+
tools: ["cron.create", "cron.list", "cron.update", "cron.delete", "cron.pause", "cron.resume", "cron.trigger", "cron.history"],
|
|
54050
|
+
triggers: ["program\xE1 una tarea", "schedule task", "cre\xE1 un cron", "create cron", "edit\xE1 el cron", "edit cron", "elimin\xE1 el cron", "remove cron", "lista las tareas", "list cron jobs", "modific\xE1 el cron", "modify cron", "tarea recurrente", "recurring task", "todos los d\xEDas", "daily", "cada semana", "weekly"],
|
|
54051
|
+
body: `
|
|
54052
|
+
# Cron Manager Skill
|
|
54053
|
+
|
|
54054
|
+
## Cu\xE1ndo se Activa
|
|
54055
|
+
|
|
54056
|
+
Para gestionar tareas programadas (cron jobs): crear, listar, actualizar, pausar, reanudar, eliminar, ejecutar y ver historial.
|
|
54057
|
+
|
|
54058
|
+
## Herramientas Disponibles
|
|
54059
|
+
|
|
54060
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54061
|
+
|------|----------|---------------|
|
|
54062
|
+
| \`cron.create\` | Crear cron job | Nueva tarea |
|
|
54063
|
+
| \`cron.list\` | Listar todos | Ver existentes |
|
|
54064
|
+
| \`cron.update\` | Actualizar existente | Cambiar horario/instrucci\xF3n |
|
|
54065
|
+
| \`cron.pause\` | Pausar temporalmente | Sin eliminar |
|
|
54066
|
+
| \`cron.resume\` | Reanudar pausado | Continuar ejecuci\xF3n |
|
|
54067
|
+
| \`cron.delete\` | Eliminar permanentemente | Cancelar para siempre |
|
|
54068
|
+
| \`cron.trigger\` | Ejecutar ahora | Forzar ejecuci\xF3n |
|
|
54069
|
+
| \`cron.history\` | Ver historial | Ver logs de ejecuciones |
|
|
54070
|
+
|
|
54071
|
+
## Campos Principales
|
|
54072
|
+
|
|
54073
|
+
| Campo | Tipo | Descripci\xF3n |
|
|
54074
|
+
|-------|------|-------------|
|
|
54075
|
+
| \`name\` | string | Identificador corto (e.g., 'daily-report') |
|
|
54076
|
+
| \`task\` | string | **REQUERIDO** - Instrucciones para el agente al ejecutarse |
|
|
54077
|
+
| \`task_type\` | string | 'recurring' (repite) o 'one_shot' (una vez) |
|
|
54078
|
+
| \`cron_expression\` | string | Expresi\xF3n cron (solo para recurring) |
|
|
54079
|
+
| \`fire_at\` | string | Datetime ISO (solo para one_shot) |
|
|
54080
|
+
| \`channel\` | string | Canal de notificaci\xF3n |
|
|
54081
|
+
| \`start_at\` | string | Inicio de ventana opcional (Croner startAt) |
|
|
54082
|
+
| \`stop_at\` | string | Fin de ventana opcional (Croner stopAt) |
|
|
54083
|
+
| \`dom_and_dow\` | number | 0=OR (default), 1=AND (d\xEDa mes + d\xEDa semana) |
|
|
54084
|
+
|
|
54085
|
+
## Cron Expression Format
|
|
54086
|
+
|
|
54087
|
+
\`\`\`
|
|
54088
|
+
* * * * *
|
|
54089
|
+
\u2502 \u2502 \u2502 \u2502 \u2502
|
|
54090
|
+
\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 D\xEDa semana (0-6, 0=Domingo)
|
|
54091
|
+
\u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500 Mes (1-12)
|
|
54092
|
+
\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500 D\xEDa del mes (1-31)
|
|
54093
|
+
\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Hora (0-23)
|
|
54094
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Minuto (0-59)
|
|
54095
|
+
\`\`\`
|
|
54096
|
+
|
|
54097
|
+
## Ejemplos Comunes
|
|
54098
|
+
|
|
54099
|
+
| Expresi\xF3n | Significado |
|
|
54100
|
+
|-----------|-------------|
|
|
54101
|
+
| \`0 9 * * *\` | Diario 9:00 AM |
|
|
54102
|
+
| \`0 7 * * 1-5\` | Lun-Vie 7:00 AM |
|
|
54103
|
+
| \`0 */2 * * *\` | Cada 2 horas |
|
|
54104
|
+
| \`0 0 * * 0\` | Domingos medianoche |
|
|
54105
|
+
| \`0 0 1 * *\` | D\xEDa 1 de cada mes |
|
|
54106
|
+
|
|
54107
|
+
## C\xF3mo Usar start_at / stop_at
|
|
54108
|
+
|
|
54109
|
+
- \`start_at\`: La tarea no ejecuta antes de esta fecha
|
|
54110
|
+
- \`stop_at\`: La tarea no ejecuta despu\xE9s de esta fecha
|
|
54111
|
+
- Formato ISO: \`'2026-04-01T00:00:00'\`
|
|
54112
|
+
|
|
54113
|
+
## C\xF3mo Usar dom_and_dow
|
|
54114
|
+
|
|
54115
|
+
- \`0\` (default): Se ejecuta si es el d\xEDa del mes O el d\xEDa de semana
|
|
54116
|
+
- \`1\`: Se ejecuta solo si es EL MISMO d\xEDa del mes Y el d\xEDa de semana
|
|
54117
|
+
|
|
54118
|
+
Ejemplo: \`0 9 15 * *\` con dom_and_dow=1 significa "los 15 de cada mes QUE SEA domingo"
|
|
54119
|
+
|
|
54120
|
+
## Workflow para Crear
|
|
54121
|
+
|
|
54122
|
+
1. **Preguntar** \u2192 \xBFone_shot o recurring?
|
|
54123
|
+
2. **Obtener** \u2192 Hora y canal de notificaci\xF3n
|
|
54124
|
+
3. **Crear** \u2192 \`cron.create\` con campo \`task\` obligatorio
|
|
54125
|
+
4. **Confirmar** \u2192 \`cron.list\` mostrar next runs
|
|
54126
|
+
|
|
54127
|
+
## Errores a Evitar
|
|
54128
|
+
|
|
54129
|
+
- \u274C Olvidar el campo \`task\` \u2014 es obligatorio
|
|
54130
|
+
- \u274C Usar exec para tareas programadas
|
|
54131
|
+
- \u274C No preguntar si es one_shot o recurring
|
|
54132
|
+
- \u274C No mostrar pr\xF3ximos horarios al crear
|
|
54133
|
+
- \u274C Llamar \`cron.update\` sin \`task_id\` \u2014 siempre hacer \`cron.list\` primero`
|
|
54134
|
+
},
|
|
54135
|
+
{
|
|
54136
|
+
name: "browser_automate",
|
|
54137
|
+
description: `Automate web workflows with navigation, clicks, form filling, and visual verification`,
|
|
54138
|
+
category: "web",
|
|
54139
|
+
version: "1.0.0",
|
|
54140
|
+
tools: ["browser_navigate", "browser_click", "browser_type", "browser_screenshot"],
|
|
54141
|
+
triggers: ["automatiz\xE1 el navegador", "automate browser", "complet\xE1 el formulario", "fill form", "hac\xE9 clic en", "click on", "inici\xE1 sesi\xF3n", "login", "registrate", "sign up", "interactu\xE1 con la web", "interact with website", "flujo web", "web workflow"],
|
|
54142
|
+
body: `
|
|
54143
|
+
# Browser Automate Skill
|
|
54144
|
+
|
|
54145
|
+
## Cu\xE1ndo se Activa
|
|
54146
|
+
|
|
54147
|
+
Esta skill se activa para automatizar flujos de interacci\xF3n con aplicaciones web: logins, formularios, navegaci\xF3n program\xE1tica.
|
|
54148
|
+
|
|
54149
|
+
## Herramientas Disponibles
|
|
54150
|
+
|
|
54151
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54152
|
+
|------|----------|---------------|
|
|
54153
|
+
| \`browser_navigate\` | Navega a URL | Inicio de flujo |
|
|
54154
|
+
| \`browser_click\` | Click en elementos | Botones, enlaces, triggers |
|
|
54155
|
+
| \`browser_type\` | Escribe en inputs | Formularios, b\xFAsquedas |
|
|
54156
|
+
| \`browser_screenshot\` | Captura estado | Verificaci\xF3n visual |
|
|
54157
|
+
|
|
54158
|
+
## Workflow T\xEDpico
|
|
54159
|
+
|
|
54160
|
+
1. **Navegar** \u2192 URL inicial
|
|
54161
|
+
2. **Interactuar** \u2192 click/type seg\xFAn flujo
|
|
54162
|
+
3. **Verificar** \u2192 screenshot despu\xE9s de acciones cr\xEDticas
|
|
54163
|
+
4. **Repetir** \u2192 para flujos multi-paso
|
|
54164
|
+
|
|
54165
|
+
## Mejores Pr\xE1cticas
|
|
54166
|
+
|
|
54167
|
+
- Selectores estables (IDs > classes > XPath)
|
|
54168
|
+
- Esperar carga despu\xE9s de navegaci\xF3n
|
|
54169
|
+
- Verificar estado visual con screenshots
|
|
54170
|
+
- Manejar errores de elementos no encontrados
|
|
54171
|
+
|
|
54172
|
+
## Errores a Evitar
|
|
54173
|
+
|
|
54174
|
+
- \u274C Selectores fr\xE1giles que cambian
|
|
54175
|
+
- \u274C No esperar carga de p\xE1gina
|
|
54176
|
+
- \u274C Ignorar errores de elementos
|
|
54177
|
+
- \u274C No verificar estado despu\xE9s de acciones
|
|
54178
|
+
`
|
|
54179
|
+
},
|
|
54180
|
+
{
|
|
54181
|
+
name: "web_research",
|
|
54182
|
+
description: `Search and synthesize information from multiple web sources into structured reports`,
|
|
54183
|
+
category: "web",
|
|
54184
|
+
version: "1.0.0",
|
|
54185
|
+
tools: ["web_search", "web_fetch"],
|
|
54186
|
+
triggers: ["investig\xE1 sobre", "research", "busc\xE1 informaci\xF3n de", "find information about", "qu\xE9 es", "what is", "explicame", "explain", "\xFAltimos avances", "latest advances", "tendencias de", "trends in", "informaci\xF3n actualizada", "current information"],
|
|
54187
|
+
body: `
|
|
54188
|
+
# Web Research Skill
|
|
54189
|
+
|
|
54190
|
+
## Cu\xE1ndo se Activa
|
|
54191
|
+
|
|
54192
|
+
Esta skill se activa cuando el usuario necesita informaci\xF3n actualizada de internet, verificar datos, o investigar temas espec\xEDficos.
|
|
54193
|
+
|
|
54194
|
+
## Herramientas Disponibles
|
|
54195
|
+
|
|
54196
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54197
|
+
|------|----------|---------------|
|
|
54198
|
+
| \`web_search\` | Busca en internet, devuelve t\xEDtulos, URLs, snippets | B\xFAsqueda inicial, encontrar fuentes |
|
|
54199
|
+
| \`web_fetch\` | Descarga contenido completo de URL (HTML\u2192Markdown) | Profundizar en resultados espec\xEDficos |
|
|
54200
|
+
|
|
54201
|
+
## Workflow
|
|
54202
|
+
|
|
54203
|
+
1. **B\xFAsqueda inicial** \u2192 \`web_search({ query, numResults: 8 })\`
|
|
54204
|
+
2. **Fetch contenido** \u2192 \`web_fetch({ urls: top 2-3 })\`
|
|
54205
|
+
3. **B\xFAsqueda complementaria** \u2192 Segundo search si hay gaps
|
|
54206
|
+
4. **S\xEDntesis** \u2192 summary + key points + sources
|
|
54207
|
+
|
|
54208
|
+
## Mejores Pr\xE1cticas
|
|
54209
|
+
|
|
54210
|
+
- Queries espec\xEDficos (m\xE1x 6 palabras)
|
|
54211
|
+
- M\xEDnimo 2-3 fuentes independientes
|
|
54212
|
+
- Priorizar contenido reciente (<1 a\xF1o)
|
|
54213
|
+
- Citas con URLs completas
|
|
54214
|
+
|
|
54215
|
+
## Errores a Evitar
|
|
54216
|
+
|
|
54217
|
+
- \u274C Inventar datos no encontrados
|
|
54218
|
+
- \u274C Concluir con una sola b\xFAsqueda
|
|
54219
|
+
- \u274C No verificar fecha de fuentes
|
|
54220
|
+
- \u274C Copiar contenido literal (usar par\xE1frasis)
|
|
54221
|
+
`
|
|
54222
|
+
},
|
|
54223
|
+
{
|
|
54224
|
+
name: "web_monitor",
|
|
54225
|
+
description: `Monitor changes in web sources and track updates over time with persistent memory`,
|
|
54226
|
+
category: "web",
|
|
54227
|
+
version: "1.0.0",
|
|
54228
|
+
tools: ["web_search", "web_fetch", "memory_write", "memory_read"],
|
|
54229
|
+
triggers: ["monitore\xE1", "monitor", "segu\xED los cambios", "track changes", "avisame si cambia", "notify if changes", "actualizaci\xF3n de", "update on", "novedades de", "news about", "cambios en", "changes in"],
|
|
54230
|
+
body: `
|
|
54231
|
+
# Web Monitor Skill
|
|
54232
|
+
|
|
54233
|
+
## Cu\xE1ndo se Activa
|
|
54234
|
+
|
|
54235
|
+
Esta skill se activa cuando el usuario necesita:
|
|
54236
|
+
- Monitorear cambios en una URL espec\xEDfica
|
|
54237
|
+
- Recibir notificaciones de actualizaciones
|
|
54238
|
+
- Seguir novedades sobre un tema
|
|
54239
|
+
- Trackear evoluci\xF3n de contenido
|
|
54240
|
+
|
|
54241
|
+
## Herramientas Disponibles
|
|
54242
|
+
|
|
54243
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54244
|
+
|------|----------|---------------|
|
|
54245
|
+
| \`web_fetch\` | Descarga contenido de URL | Obtener contenido actual |
|
|
54246
|
+
| \`web_search\` | Busca novedades | Monitoreo por tema (no URL fija) |
|
|
54247
|
+
| \`memory_write\` | Guarda baseline | Almacenar contenido para comparaci\xF3n |
|
|
54248
|
+
| \`memory_read\` | Recupera baseline anterior | Comparar con contenido actual |
|
|
54249
|
+
|
|
54250
|
+
## Workflow
|
|
54251
|
+
|
|
54252
|
+
1. **Primera ejecuci\xF3n**: \`web_fetch\` \u2192 \`memory_write\` (baseline)
|
|
54253
|
+
2. **Chequeos siguientes**: \`memory_read\` \u2192 \`web_fetch\` \u2192 comparar \u2192 \`notify\` si cambia
|
|
54254
|
+
3. **Actualizar baseline**: \`memory_write\` con nuevo contenido
|
|
54255
|
+
|
|
54256
|
+
## Mejores Pr\xE1cticas
|
|
54257
|
+
|
|
54258
|
+
- Ignorar cambios menores (timestamps, ads, contenido din\xE1mico irrelevante)
|
|
54259
|
+
- Notificar solo cambios significativos
|
|
54260
|
+
- Para monitoreo peri\xF3dico, combinar con \`cron.create\`
|
|
54261
|
+
|
|
54262
|
+
## Errores a Evitar
|
|
54263
|
+
|
|
54264
|
+
- \u274C No almacenar baseline inicial
|
|
54265
|
+
- \u274C Notificar por cambios triviales
|
|
54266
|
+
- \u274C No actualizar timestamp de baseline
|
|
54267
|
+
`
|
|
54268
|
+
},
|
|
54269
|
+
{
|
|
54270
|
+
name: "browser_scrape",
|
|
54271
|
+
description: `Navigate to web pages and capture rendered content including screenshots for dynamic sites`,
|
|
54272
|
+
category: "web",
|
|
54273
|
+
version: "1.0.0",
|
|
54274
|
+
tools: ["browser_navigate", "browser_screenshot", "web_fetch"],
|
|
54275
|
+
triggers: ["captur\xE1 el contenido", "scrape content", "obten\xE9 la p\xE1gina renderizada", "get rendered page", "sitios din\xE1micos", "dynamic sites", "web con javascript", "javascript websites", "tom\xE1 screenshot y contenido", "screenshot and content"],
|
|
54276
|
+
body: `
|
|
54277
|
+
# Browser Scrape Skill
|
|
54278
|
+
|
|
54279
|
+
## Cu\xE1ndo se Activa
|
|
54280
|
+
|
|
54281
|
+
Esta skill se activa para sitios web din\xE1micos que requieren JavaScript rendering, donde el contenido no est\xE1 disponible en HTML est\xE1tico.
|
|
54282
|
+
|
|
54283
|
+
## Herramientas Disponibles
|
|
54284
|
+
|
|
54285
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54286
|
+
|------|----------|---------------|
|
|
54287
|
+
| \`browser_navigate\` | Navega y renderiza p\xE1gina completa | Sitios con JavaScript/SPA |
|
|
54288
|
+
| \`browser_screenshot\` | Captura estado visual | Evidencia de contenido renderizado |
|
|
54289
|
+
| \`web_fetch\` | Extrae texto como markdown | Contenido textual de p\xE1gina renderizada |
|
|
54290
|
+
|
|
54291
|
+
## Workflow
|
|
54292
|
+
|
|
54293
|
+
1. **Navegar** \u2192 \`browser_navigate({ url })\` + esperar renderizado JS
|
|
54294
|
+
2. **Capturar visual** \u2192 \`browser_screenshot()\`
|
|
54295
|
+
3. **Extraer texto** \u2192 \`web_fetch()\`
|
|
54296
|
+
4. **Combinar** \u2192 screenshot + texto para scrape completo
|
|
54297
|
+
|
|
54298
|
+
## Mejores Pr\xE1cticas
|
|
54299
|
+
|
|
54300
|
+
- Esperar renderizado completo de JavaScript
|
|
54301
|
+
- Para infinite scroll: hacer scroll y m\xFAltiples screenshots
|
|
54302
|
+
- Capturar antes y despu\xE9s de interacciones si es din\xE1mico
|
|
54303
|
+
|
|
54304
|
+
## Errores a Evitar
|
|
54305
|
+
|
|
54306
|
+
- \u274C No esperar renderizado JavaScript
|
|
54307
|
+
- \u274C Solo capturar HTML est\xE1tico para sitios SPA
|
|
54308
|
+
- \u274C Ignorar t\xE9rminos de servicio del sitio
|
|
54309
|
+
`
|
|
54310
|
+
},
|
|
54311
|
+
{
|
|
54312
|
+
name: "busqueda_fts5",
|
|
54313
|
+
description: `Core discovery skill - find any capability with a single keyword`,
|
|
54314
|
+
category: "core",
|
|
54315
|
+
version: "1.2.0",
|
|
54316
|
+
tools: ["search_knowledge"],
|
|
54317
|
+
triggers: ["c\xF3mo busco herramientas", "c\xF3mo encuentro skills", "how to find tools", "search knowledge", "discovery", "buscar en la base", "encontrar herramientas"],
|
|
54318
|
+
body: `
|
|
54319
|
+
# busqueda_fts5 \u2014 Sistema de Discovery
|
|
54320
|
+
|
|
54321
|
+
Arranc\xE1s con solo 4 herramientas. Todo lo dem\xE1s se descubre con **search_knowledge**.
|
|
54322
|
+
|
|
54323
|
+
## Regla de oro: UNA PALABRA, busca TODO
|
|
54324
|
+
|
|
54325
|
+
\`\`\`
|
|
54326
|
+
search_knowledge(query="email")
|
|
54327
|
+
\`\`\`
|
|
54328
|
+
|
|
54329
|
+
Eso solo \u2014 sin type, sin frases largas \u2014 devuelve tools, skills, MCP y playbook relacionados con "email".
|
|
54330
|
+
|
|
54331
|
+
**NO hagas esto:** \`search_knowledge(type="tools", query="enviar correo electr\xF3nico")\` \u2014 AND entre palabras no encuentra nada.
|
|
54332
|
+
|
|
54333
|
+
**S\xCD hagas esto:** \`search_knowledge(query="email")\` \u2014 encuentra todo lo relacionado.
|
|
54334
|
+
|
|
54335
|
+
## Cu\xE1ndo especificar type
|
|
54336
|
+
|
|
54337
|
+
Solo si quer\xE9s filtrar resultados que ya son muchos:
|
|
54338
|
+
|
|
54339
|
+
\`\`\`
|
|
54340
|
+
search_knowledge(query="email", type="mcp") \u2192 solo herramientas externas de email
|
|
54341
|
+
search_knowledge(query="email", type="tools") \u2192 solo herramientas nativas de email
|
|
54342
|
+
\`\`\`
|
|
54343
|
+
|
|
54344
|
+
Por defecto type="all" \u2014 no hace falta especificarlo.
|
|
54345
|
+
|
|
54346
|
+
## Regla de prioridad
|
|
54347
|
+
|
|
54348
|
+
**Prefer\xED herramientas nativas sobre MCP** cuando ambas sirven.
|
|
54349
|
+
- Nativas: m\xE1s r\xE1pidas, sin red, siempre disponibles
|
|
54350
|
+
- MCP: cuando no hay equivalente nativo
|
|
54351
|
+
|
|
54352
|
+
## Flujo de uso
|
|
54353
|
+
|
|
54354
|
+
1. Identific\xE1 la palabra clave de lo que necesit\xE1s
|
|
54355
|
+
2. \`search_knowledge(query="<palabra>")\` \u2192 resultados de todos los tipos
|
|
54356
|
+
3. Las tools encontradas se inyectan autom\xE1ticamente en tu contexto
|
|
54357
|
+
4. Us\xE1s las tools en el siguiente paso
|
|
54358
|
+
|
|
54359
|
+
---
|
|
54360
|
+
|
|
54361
|
+
## Ejemplos
|
|
54362
|
+
|
|
54363
|
+
\`\`\`
|
|
54364
|
+
search_knowledge(query="pdf") \u2192 tools para leer/escribir PDFs
|
|
54365
|
+
search_knowledge(query="browser") \u2192 tools de navegaci\xF3n web
|
|
54366
|
+
search_knowledge(query="github") \u2192 tools MCP de GitHub si est\xE1n configuradas
|
|
54367
|
+
search_knowledge(query="calendar") \u2192 tools de Google Calendar
|
|
54368
|
+
search_knowledge(query="canvas") \u2192 skills de visualizaci\xF3n
|
|
54369
|
+
search_knowledge(query="slack") \u2192 tools de Slack si est\xE1n configuradas
|
|
54370
|
+
\`\`\`
|
|
54371
|
+
`
|
|
54372
|
+
},
|
|
54373
|
+
{
|
|
54374
|
+
name: "api_client",
|
|
54375
|
+
description: `Make HTTP requests to REST APIs using curl-like methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)`,
|
|
54376
|
+
category: "api",
|
|
54377
|
+
version: "1.0.0",
|
|
54378
|
+
tools: ["api_request"],
|
|
54379
|
+
triggers: ["llama a la api", "llama al api", "consume la api", "haz una petici\xF3n", "haz un request", "env\xEDa un post", "env\xEDa un put", "env\xEDa un delete", "curl", "api request", "rest api", "endpoint", "webhook", "integrar con api", "conectar con api", "obtener datos de api", "enviar datos a api"],
|
|
54380
|
+
body: `
|
|
54381
|
+
# API Client Skill
|
|
54382
|
+
|
|
54383
|
+
## Cu\xE1ndo se Activa
|
|
54384
|
+
|
|
54385
|
+
Esta skill se activa cuando el usuario necesita interactuar con una API REST: consultar datos, crear recursos, actualizar, eliminar, o cualquier operaci\xF3n HTTP.
|
|
54386
|
+
|
|
54387
|
+
## Herramientas Disponibles
|
|
54388
|
+
|
|
54389
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54390
|
+
|------|----------|---------------|
|
|
54391
|
+
| \`api_request\` | Realiza peticiones HTTP completas (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) con headers, body, query params y timeout | Siempre que necesites llamar un endpoint REST, webhook, o servicio externo |
|
|
54392
|
+
|
|
54393
|
+
## Par\xE1metros de api_request
|
|
54394
|
+
|
|
54395
|
+
- \`method\` (requerido): GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
|
|
54396
|
+
- \`url\` (requerido): URL completa del endpoint
|
|
54397
|
+
- \`headers\` (opcional): objeto con headers HTTP. Ej: \`{ "Authorization": "Bearer TOKEN", "Content-Type": "application/json" }\`
|
|
54398
|
+
- \`body\` (opcional): cuerpo de la petici\xF3n como string. Para JSON, enviar JSON.stringify(objeto)
|
|
54399
|
+
- \`query_params\` (opcional): par\xE1metros de query que se codificar\xE1n autom\xE1ticamente en la URL
|
|
54400
|
+
- \`timeout_ms\` (opcional): timeout en ms. Default: 30000. M\xE1x: 120000
|
|
54401
|
+
|
|
54402
|
+
## Diferencia con web_fetch
|
|
54403
|
+
|
|
54404
|
+
- \`web_fetch\`: solo GET, sin headers custom, ideal para scraping de p\xE1ginas web
|
|
54405
|
+
- \`api_request\`: cualquier m\xE9todo HTTP, headers custom, body, query params \u2014 ideal para APIs REST
|
|
54406
|
+
|
|
54407
|
+
## Workflow
|
|
54408
|
+
|
|
54409
|
+
1. **Identificar endpoint y m\xE9todo** \u2192 Determinar URL, m\xE9todo, headers necesarios
|
|
54410
|
+
2. **Construir request** \u2192 \`api_request({ method, url, headers, body })\`
|
|
54411
|
+
3. **Validar respuesta** \u2192 Si 2xx: extraer datos. Si error: analizar y sugerir fix
|
|
54412
|
+
4. **Presentar resultados** \u2192 JSON parseado en formato legible, no crudo a menos que se pida
|
|
54413
|
+
|
|
54414
|
+
## Mejores Pr\xE1cticas
|
|
54415
|
+
|
|
54416
|
+
- Siempre enviar \`Content-Type: application/json\` cuando el body es JSON
|
|
54417
|
+
- Usar \`query_params\` en lugar de append manual a la URL
|
|
54418
|
+
- No exponer tokens/secrets en la respuesta final al usuario
|
|
54419
|
+
- Si la API requiere auth, pedirla al usuario o usar variables de entorno
|
|
54420
|
+
- Para errores 4xx, revisar: auth, formato del body, campos requeridos, rate limits
|
|
54421
|
+
|
|
54422
|
+
## Errores a Evitar
|
|
54423
|
+
|
|
54424
|
+
- \u274C Usar web_fetch para POST/PUT/DELETE con headers
|
|
54425
|
+
- \u274C Enviar objetos directamente en body (debe ser string)
|
|
54426
|
+
- \u274C Olvidar Content-Type al enviar JSON
|
|
54427
|
+
- \u274C Exponer API keys en la respuesta visible
|
|
54428
|
+
`
|
|
54429
|
+
},
|
|
54430
|
+
{
|
|
54431
|
+
name: "file_manager",
|
|
54432
|
+
description: `Explore project structure and locate files using glob patterns and directory listing`,
|
|
54433
|
+
category: "filesystem",
|
|
54434
|
+
version: "1.0.0",
|
|
54435
|
+
tools: ["fs_list", "fs_glob", "fs_exists"],
|
|
54436
|
+
triggers: ["lista los archivos", "list files", "busc\xE1 archivos", "find files", "explor\xE1 el proyecto", "explore project", "qu\xE9 archivos hay", "what files exist", "busc\xE1 por patr\xF3n", "search by pattern", "existe este archivo", "file exists", "d\xF3nde est\xE1", "where is"],
|
|
54437
|
+
body: `
|
|
54438
|
+
# File Manager Skill
|
|
54439
|
+
|
|
54440
|
+
## Cu\xE1ndo se Activa
|
|
54441
|
+
|
|
54442
|
+
Esta skill se activa cuando el usuario necesita:
|
|
54443
|
+
- Explorar la estructura del proyecto
|
|
54444
|
+
- Buscar archivos por extensi\xF3n o patr\xF3n
|
|
54445
|
+
- Verificar si existe un archivo o directorio
|
|
54446
|
+
- Encontrar la ubicaci\xF3n de un archivo
|
|
54447
|
+
|
|
54448
|
+
## Herramientas Disponibles
|
|
54449
|
+
|
|
54450
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54451
|
+
|------|----------|---------------|
|
|
54452
|
+
| \`fs_list\` | Lista directorios y archivos | Exploraci\xF3n inicial |
|
|
54453
|
+
| \`fs_glob\` | Busca archivos por patr\xF3n wildcard | B\xFAsqueda por extensi\xF3n/patr\xF3n |
|
|
54454
|
+
| \`fs_exists\` | Verifica existencia | Pre-check antes de operaciones |
|
|
54455
|
+
|
|
54456
|
+
## Workflow
|
|
54457
|
+
|
|
54458
|
+
1. **Explorar** \u2192 \`fs_list({ path })\` para estructura general
|
|
54459
|
+
2. **Buscar por patr\xF3n** \u2192 \`fs_glob({ pattern })\` para tipos espec\xEDficos
|
|
54460
|
+
3. **Verificar** \u2192 \`fs_exists({ path })\` para confirmaci\xF3n
|
|
54461
|
+
|
|
54462
|
+
## Patrones Glob Comunes
|
|
54463
|
+
|
|
54464
|
+
| Patr\xF3n | Encuentra |
|
|
54465
|
+
|--------|-----------|
|
|
54466
|
+
| \`**/*.ts\` | Todos los TypeScript |
|
|
54467
|
+
| \`**/*.test.ts\` | Solo tests |
|
|
54468
|
+
| \`**/*.md\` | Documentaci\xF3n |
|
|
54469
|
+
| \`**/package.json\` | Todos los package.json |
|
|
54470
|
+
| \`src/**/*.tsx\` | React components en src |
|
|
54471
|
+
|
|
54472
|
+
## Errores a Evitar
|
|
54473
|
+
|
|
54474
|
+
- \u274C No verificar existencia antes de leer/editar
|
|
54475
|
+
- \u274C Usar fs_list cuando se conoce el patr\xF3n (usar glob)
|
|
54476
|
+
- \u274C Patrones muy amplios sin filtrado
|
|
54477
|
+
`
|
|
54478
|
+
},
|
|
54479
|
+
{
|
|
54480
|
+
name: "file_writer",
|
|
54481
|
+
description: `Create, modify, and delete files with safe edit operations and confirmation for large changes`,
|
|
54482
|
+
category: "filesystem",
|
|
54483
|
+
version: "1.0.0",
|
|
54484
|
+
tools: ["project_read", "project_write", "project_edit", "project_exists"],
|
|
54485
|
+
triggers: ["cre\xE1 un archivo", "create a file", "escrib\xED en", "write to", "edit\xE1 este archivo", "edit this file", "modific\xE1", "modify", "elimin\xE1 el archivo", "delete file", "guard\xE1 esto", "save this", "actualiz\xE1 el archivo", "update file"],
|
|
54486
|
+
body: `
|
|
54487
|
+
# File Writer Skill
|
|
54488
|
+
|
|
54489
|
+
## Cu\xE1ndo se Activa
|
|
54490
|
+
|
|
54491
|
+
Esta skill se activa cuando el usuario necesita:
|
|
54492
|
+
- Crear nuevos archivos
|
|
54493
|
+
- Modificar contenido existente
|
|
54494
|
+
- Eliminar archivos
|
|
54495
|
+
- Guardar cambios
|
|
54496
|
+
|
|
54497
|
+
## Herramientas Disponibles
|
|
54498
|
+
|
|
54499
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54500
|
+
|------|----------|---------------|
|
|
54501
|
+
| \`project_read\` | Lee archivo existente | Antes de editar para entender estructura |
|
|
54502
|
+
| \`project_write\` | Crea o sobreescribe archivo | Archivos nuevos o reescritura completa |
|
|
54503
|
+
| \`project_edit\` | Edita secciones espec\xEDficas | Cambios puntuales (find/replace) |
|
|
54504
|
+
| \`project_exists\` | Verifica existencia | Para decidir crear vs editar |
|
|
54505
|
+
|
|
54506
|
+
## Workflow
|
|
54507
|
+
|
|
54508
|
+
### Crear Archivo Nuevo
|
|
54509
|
+
1. \`project_exists({ path })\` \u2192 verificar no existe
|
|
54510
|
+
2. \`project_write({ path, content })\` \u2192 crear
|
|
54511
|
+
|
|
54512
|
+
### Editar Archivo Existente
|
|
54513
|
+
1. \`project_exists({ path })\` \u2192 verificar existe
|
|
54514
|
+
2. \`project_read({ path })\` \u2192 entender estructura
|
|
54515
|
+
3. \`project_edit({ path, old_string, new_string })\` \u2192 modificar
|
|
54516
|
+
4. \`canvas_confirm()\` si cambios >50 l\xEDneas
|
|
54517
|
+
|
|
54518
|
+
### Eliminar Archivo
|
|
54519
|
+
1. \`project_exists({ path })\` \u2192 verificar existe
|
|
54520
|
+
2. \`canvas_confirm({ message: '\xBFEliminar archivo?' })\` \u2192 confirmar
|
|
54521
|
+
3. Operaci\xF3n de delete
|
|
54522
|
+
|
|
54523
|
+
## Mejores Pr\xE1cticas
|
|
54524
|
+
|
|
54525
|
+
- **Leer antes de editar**: Nunca modificar sin entender estructura
|
|
54526
|
+
- **Edit vs Write**: Usar edit para cambios peque\xF1os, write para nuevos archivos
|
|
54527
|
+
- **Confirmar cambios grandes**: >50 l\xEDneas requiere confirmaci\xF3n expl\xEDcita
|
|
54528
|
+
- **Paths seguros**: Trabajar dentro del workspace por defecto
|
|
54529
|
+
|
|
54530
|
+
## Errores a Evitar
|
|
54531
|
+
|
|
54532
|
+
- \u274C Editar sin leer primero
|
|
54533
|
+
- \u274C Sobreescribir sin confirmar si es cambio grande
|
|
54534
|
+
- \u274C Eliminar sin confirmaci\xF3n expl\xEDcita
|
|
54535
|
+
- \u274C Usar write cuando edit es suficiente
|
|
54536
|
+
`
|
|
54537
|
+
},
|
|
54538
|
+
{
|
|
54539
|
+
name: "file_read_and_summarize",
|
|
54540
|
+
description: `Read and understand file content with automatic summarization for large files`,
|
|
54541
|
+
category: "filesystem",
|
|
54542
|
+
version: "1.0.0",
|
|
54543
|
+
tools: ["project_read"],
|
|
54544
|
+
triggers: ["le\xE9 este archivo", "read this file", "mostrame el contenido", "show content", "qu\xE9 dice este archivo", "resum\xED este archivo", "summarize this file", "entend\xE9 este c\xF3digo", "understand this code"],
|
|
54545
|
+
body: `
|
|
54546
|
+
# File Read and Summarize Skill
|
|
54547
|
+
|
|
54548
|
+
## Cu\xE1ndo se Activa
|
|
54549
|
+
|
|
54550
|
+
Esta skill se activa cuando el usuario necesita leer y entender el contenido de un archivo, especialmente cuando:
|
|
54551
|
+
- El archivo es grande y necesita resumen
|
|
54552
|
+
- Se requiere comprensi\xF3n del contenido (no solo lectura)
|
|
54553
|
+
- El usuario pide "qu\xE9 dice", "resum\xED", "entend\xE9"
|
|
54554
|
+
|
|
54555
|
+
## Herramientas Disponibles
|
|
54556
|
+
|
|
54557
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54558
|
+
|------|----------|---------------|
|
|
54559
|
+
| \`project_read\` | Lee contenido de archivo del workspace | Lectura de cualquier archivo |
|
|
54560
|
+
|
|
54561
|
+
## Workflow
|
|
54562
|
+
|
|
54563
|
+
1. **Verificar existencia** \u2192 \`project_exists({ path })\`
|
|
54564
|
+
2. **Leer contenido** \u2192 \`project_read({ path, offset, limit })\`
|
|
54565
|
+
3. **Sintetizar** \u2192 Resumir si es grande, extraer puntos clave
|
|
54566
|
+
|
|
54567
|
+
## Mejores Pr\xE1cticas
|
|
54568
|
+
|
|
54569
|
+
- Para archivos >1000 l\xEDneas, usar \`offset\` y \`limit\`
|
|
54570
|
+
- Identificar tipo de archivo por extensi\xF3n y adaptar formato de resumen
|
|
54571
|
+
- Para c\xF3digo: identificar funciones, clases, exports principales
|
|
54572
|
+
- Para config: explicar settings clave en lenguaje simple
|
|
54573
|
+
- Para texto: extraer ideas principales
|
|
54574
|
+
|
|
54575
|
+
## Errores a Evitar
|
|
54576
|
+
|
|
54577
|
+
- \u274C Leer sin verificar existencia
|
|
54578
|
+
- \u274C Retornar archivo completo sin resumir si es muy grande
|
|
54579
|
+
- \u274C No identificar tipo de archivo para adaptar resumen
|
|
54580
|
+
`
|
|
54581
|
+
},
|
|
53825
54582
|
{
|
|
53826
54583
|
name: "office_document_manager",
|
|
53827
54584
|
description: `Leer, crear y manipular archivos Office (PDF, Word, Excel, PowerPoint) desde el workspace`,
|
|
@@ -53921,6 +54678,225 @@ Esta skill se activa cuando el usuario necesita:
|
|
|
53921
54678
|
- \u274C Pasar un array de arrays como \`datos\` de XLSX cuando se esperan objetos con claves
|
|
53922
54679
|
- \u274C Intentar leer PDF de m\xE1s de 100 p\xE1ginas sin especificar rango (usar \`pagina_inicio\`/\`pagina_fin\`)
|
|
53923
54680
|
`
|
|
54681
|
+
},
|
|
54682
|
+
{
|
|
54683
|
+
name: "cron_reminder",
|
|
54684
|
+
description: `Schedule a reminder for yourself at a specific time. Creates a one_shot cron job that sends a notification message via your preferred channel.`,
|
|
54685
|
+
category: "cron",
|
|
54686
|
+
version: "2.0.0",
|
|
54687
|
+
tools: ["cron.create", "notify"],
|
|
54688
|
+
triggers: ["recordame", "remind me", "recordatorio", "reminder", "alerta", "alert", "av\xEDsame", "notify me", "program\xE1", "schedule", "para ma\xF1ana", "for tomorrow", "en 30 minutos", "in 30 minutes"],
|
|
54689
|
+
body: `
|
|
54690
|
+
# Cron Reminder Skill
|
|
54691
|
+
|
|
54692
|
+
## Cu\xE1ndo se Activa
|
|
54693
|
+
|
|
54694
|
+
Para crear recordatorios de una sola ejecuci\xF3n (one_shot): "recuerdame a las 3pm", "av\xEDsame en 30 minutos", etc.
|
|
54695
|
+
|
|
54696
|
+
## Herramientas
|
|
54697
|
+
|
|
54698
|
+
| Tool | Qu\xE9 hace |
|
|
54699
|
+
|------|----------|
|
|
54700
|
+
| \`cron.create\` | Crear recordatorio one_shot |
|
|
54701
|
+
| \`notify\` | Enviar notificaci\xF3n directa |
|
|
54702
|
+
|
|
54703
|
+
## C\xF3mo Funciona
|
|
54704
|
+
|
|
54705
|
+
1. **Preguntar** \u2192 \xBFDe qu\xE9 te aviso? \xBFA qu\xE9 hora? \xBFPor qu\xE9 canal?
|
|
54706
|
+
2. **Crear** \u2192 \`cron.create\` con \`task_type: 'one_shot'\` y \`fire_at\` en formato ISO
|
|
54707
|
+
3. **Confirmar** \u2192 Mostrar hora programada
|
|
54708
|
+
|
|
54709
|
+
## Par\xE1metros
|
|
54710
|
+
|
|
54711
|
+
| Campo | Descripci\xF3n |
|
|
54712
|
+
|-------|-------------|
|
|
54713
|
+
| \`task\` | **REQUERIDO** - Mensaje del recordatorio |
|
|
54714
|
+
| \`task_type\` | Siempre \`'one_shot'\` |
|
|
54715
|
+
| \`fire_at\` | Fecha/hora ISO (ej: \`'2026-04-20T15:00:00'\`) |
|
|
54716
|
+
| \`channel\` | Canal (telegram, discord, whatsapp, webchat) |
|
|
54717
|
+
|
|
54718
|
+
## Errores Comunes
|
|
54719
|
+
|
|
54720
|
+
- \u274C Olvidar el campo \`task\` \u2014 obligatorio para que el agente sepa qu\xE9 enviar
|
|
54721
|
+
- \u274C Usar expresiones cron para recordatorios (usar \`fire_at\` en vez de \`cron_expression\`)
|
|
54722
|
+
- \u274C Poner \`fire_at\` en el pasado`
|
|
54723
|
+
},
|
|
54724
|
+
{
|
|
54725
|
+
name: "canvas_dashboard",
|
|
54726
|
+
description: `Real-time visual dashboard for monitoring task status, progress, and system state`,
|
|
54727
|
+
category: "canvas",
|
|
54728
|
+
version: "1.0.0",
|
|
54729
|
+
tools: ["canvas_render", "canvas_show_progress", "canvas_clear"],
|
|
54730
|
+
triggers: ["mostr\xE1 el dashboard", "show dashboard", "estado en tiempo real", "real-time status", "monitoreo visual", "visual monitoring", "panel de control", "control panel", "limpi\xE1 el canvas", "clear canvas", "actualiz\xE1 el dashboard", "update dashboard"],
|
|
54731
|
+
body: `
|
|
54732
|
+
# Canvas Dashboard Skill
|
|
54733
|
+
|
|
54734
|
+
## Cu\xE1ndo se Activa
|
|
54735
|
+
|
|
54736
|
+
Para mostrar dashboards visuales de monitoreo en tiempo real de tareas, proyectos, o estado del sistema.
|
|
54737
|
+
|
|
54738
|
+
## Herramientas Disponibles
|
|
54739
|
+
|
|
54740
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54741
|
+
|------|----------|---------------|
|
|
54742
|
+
| \`canvas_render\` | Renderiza componentes | Layout del dashboard |
|
|
54743
|
+
| \`canvas_show_progress\` | Barras de progreso | Estado de tasks |
|
|
54744
|
+
| \`canvas_clear\` | Limpia canvas | Antes de nuevo dashboard |
|
|
54745
|
+
|
|
54746
|
+
## Workflow
|
|
54747
|
+
|
|
54748
|
+
1. **Clear** \u2192 \`canvas_clear()\` \u2014 limpiar previo
|
|
54749
|
+
2. **Render layout** \u2192 \`canvas_render({ sections })\`
|
|
54750
|
+
3. **Update progress** \u2192 \`canvas_show_progress()\` en tiempo real
|
|
54751
|
+
4. **Refresh** \u2192 \`canvas_render({ updates })\` para cambios
|
|
54752
|
+
|
|
54753
|
+
## Estructura de Dashboard
|
|
54754
|
+
|
|
54755
|
+
\`\`\`javascript
|
|
54756
|
+
canvas_render({
|
|
54757
|
+
component: {
|
|
54758
|
+
id: "dashboard-main",
|
|
54759
|
+
type: "markdown",
|
|
54760
|
+
props: { content: "## Dashboard\\n..." },
|
|
54761
|
+
span: "full" // \u2190 ancho completo del canvas
|
|
54762
|
+
}
|
|
54763
|
+
})
|
|
54764
|
+
|
|
54765
|
+
// O con tarjetas individuales:
|
|
54766
|
+
canvas_show_card({ title: "M\xE9tricas", span: "full", items: [...] })
|
|
54767
|
+
canvas_show_progress({ tasks: [...], span: "full" })
|
|
54768
|
+
\`\`\`
|
|
54769
|
+
|
|
54770
|
+
## Color Coding
|
|
54771
|
+
|
|
54772
|
+
| Color | Estado |
|
|
54773
|
+
|-------|--------|
|
|
54774
|
+
| \uD83D\uDFE2 Verde | Complete |
|
|
54775
|
+
| \uD83D\uDD35 Azul | In Progress |
|
|
54776
|
+
| \uD83D\uDD34 Rojo | Error/Blocked |
|
|
54777
|
+
| \uD83D\uDFE1 Amarillo | Pending |
|
|
54778
|
+
|
|
54779
|
+
## Mejores Pr\xE1cticas
|
|
54780
|
+
|
|
54781
|
+
- Clear antes de renderizar nuevo dashboard
|
|
54782
|
+
- Layout consistente (header, progress, status, metrics)
|
|
54783
|
+
- Update en tiempo real con progreso
|
|
54784
|
+
- Solo informaci\xF3n cr\xEDtica (no sobrecargar)
|
|
54785
|
+
|
|
54786
|
+
## Errores a Evitar
|
|
54787
|
+
|
|
54788
|
+
- \u274C No clear entre dashboards (clutter)
|
|
54789
|
+
- \u274C Demasiada informaci\xF3n (sobrecarga visual)
|
|
54790
|
+
- \u274C No actualizar en tiempo real
|
|
54791
|
+
- \u274C Sin color coding para estados
|
|
54792
|
+
`
|
|
54793
|
+
},
|
|
54794
|
+
{
|
|
54795
|
+
name: "a2ui_interactive",
|
|
54796
|
+
description: `Create multi-step interactive workflows using A2UI v0.9 protocol with tabs, modals, choice pickers, and dynamic updates based on user actions`,
|
|
54797
|
+
category: "canvas",
|
|
54798
|
+
version: "1.0.0",
|
|
54799
|
+
tools: ["a2ui_create_surface", "a2ui_update_components", "a2ui_update_data_model", "a2ui_delete_surface"],
|
|
54800
|
+
triggers: ["interfaz interactiva A2UI", "A2UI interactive UI", "flujo A2UI", "A2UI workflow", "asistente A2UI", "A2UI assistant", "wizard A2UI", "flujo multi-paso A2UI", "multi-step flow A2UI", "workflow interactivo", "interactive workflow", "asistente paso a paso", "step-by-step assistant", "A2UI con tabs y modales"],
|
|
54801
|
+
body: `
|
|
54802
|
+
# A2UI Interactive Skill
|
|
54803
|
+
|
|
54804
|
+
## Cu\xE1ndo se Activa
|
|
54805
|
+
|
|
54806
|
+
Para crear flujos interactivos multi-paso usando A2UI v0.9. Usar cuando se necesita:
|
|
54807
|
+
- Wizards paso a paso
|
|
54808
|
+
- Flujos de onboarding
|
|
54809
|
+
- Asistentes de reserva/configuraci\xF3n
|
|
54810
|
+
- Formularios con selections din\xE1micas
|
|
54811
|
+
- Interacciones con modales de confirmaci\xF3n
|
|
54812
|
+
- UIs que cambian seg\xFAn las acciones del usuario
|
|
54813
|
+
|
|
54814
|
+
## Herramientes Disponibles
|
|
54815
|
+
|
|
54816
|
+
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54817
|
+
|------|----------|---------------|
|
|
54818
|
+
| \`a2ui_create_surface\` | Crea la superficie A2UI | Siempre primero |
|
|
54819
|
+
| \`a2ui_update_components\` | Env\xEDa/actualiza componentes | Para layout y cambios de UI |
|
|
54820
|
+
| \`a2ui_update_data_model\` | Actualiza datos | Para estado del workflow |
|
|
54821
|
+
| \`a2ui_delete_surface\` | Elimina la superficie | Al terminar flujo |
|
|
54822
|
+
|
|
54823
|
+
## Flujo Obligatorio
|
|
54824
|
+
|
|
54825
|
+
\`\`\`
|
|
54826
|
+
1. a2ui_create_surface(surfaceId, catalogId, theme)
|
|
54827
|
+
2. a2ui_update_components(surfaceId, components[])
|
|
54828
|
+
3. a2ui_update_data_model(surfaceId, path, value) // estado inicial
|
|
54829
|
+
4. [recibir acci\xF3n del usuario]
|
|
54830
|
+
5. a2ui_update_data_model(...) // actualizar estado con respuesta
|
|
54831
|
+
6. a2ui_update_components(...) // cambiar UI al siguiente paso
|
|
54832
|
+
7. ... repetir 4-6 seg\xFAn necesidad ...
|
|
54833
|
+
8. a2ui_delete_surface(surfaceId) // al terminar
|
|
54834
|
+
\`\`\`
|
|
54835
|
+
|
|
54836
|
+
## Patrones de Flujo Interactivo
|
|
54837
|
+
|
|
54838
|
+
### Wizard con Tabs (multi-paso)
|
|
54839
|
+
|
|
54840
|
+
\`\`\`json
|
|
54841
|
+
[
|
|
54842
|
+
{id: "root", component: "Column", children: ["step_indicator", "tabs"]},
|
|
54843
|
+
{id: "step_indicator", component: "Text", text: {path: "/stepLabel"}, variant: "caption"},
|
|
54844
|
+
{id: "tabs", component: "Tabs", tabs: [
|
|
54845
|
+
{title: "Servicio", child: "step1"},
|
|
54846
|
+
{title: "Fecha", child: "step2"},
|
|
54847
|
+
{title: "Confirmar", child: "step3"}
|
|
54848
|
+
]},
|
|
54849
|
+
{id: "step1", component: "Column", children: ["svc_label", "svc_picker"]},
|
|
54850
|
+
{id: "svc_label", component: "Text", text: "Seleccion\xE1 un servicio", variant: "h3"},
|
|
54851
|
+
{id: "svc_picker", component: "ChoicePicker", variant: "mutuallyExclusive", options: [...], value: {path: "/data/service"}},
|
|
54852
|
+
// ... m\xE1s pasos
|
|
54853
|
+
]
|
|
54854
|
+
\`\`\`
|
|
54855
|
+
|
|
54856
|
+
### Confirmaci\xF3n con Modal
|
|
54857
|
+
|
|
54858
|
+
\`\`\`json
|
|
54859
|
+
[
|
|
54860
|
+
{id: "confirm_modal", component: "Modal", trigger: "confirm_btn", content: "confirm_dialog"},
|
|
54861
|
+
{id: "confirm_btn", component: "Button", child: "confirm_btn_text", action: {}},
|
|
54862
|
+
{id: "confirm_btn_text", component: "Text", text: "Confirmar Reserva"},
|
|
54863
|
+
{id: "confirm_dialog", component: "Column", children: ["confirm_msg", "confirm_yes", "confirm_no"]},
|
|
54864
|
+
{id: "confirm_msg", component: "Text", text: "\xBFConfirm\xE1s tu reserva?"},
|
|
54865
|
+
{id: "confirm_yes", component: "Button", child: "yes_text", variant: "primary", action: {event: {name: "confirm_booking", context: {service: {path: "/data/service"}}}}},
|
|
54866
|
+
{id: "yes_text", component: "Text", text: "S\xED, confirmar"},
|
|
54867
|
+
{id: "confirm_no", component: "Button", child: "no_text", variant: "borderless", action: {event: {name: "cancel"}}}},
|
|
54868
|
+
{id: "no_text", component: "Text", text: "Cancelar"}
|
|
54869
|
+
]
|
|
54870
|
+
\`\`\`
|
|
54871
|
+
|
|
54872
|
+
### Selecci\xF3n con ChoicePicker
|
|
54873
|
+
|
|
54874
|
+
\`\`\`json
|
|
54875
|
+
[
|
|
54876
|
+
{id: "service_picker", component: "ChoicePicker",
|
|
54877
|
+
variant: "mutuallyExclusive",
|
|
54878
|
+
options: [
|
|
54879
|
+
{label: "Consulta General", value: "general"},
|
|
54880
|
+
{label: "Especializada", value: "specialist"},
|
|
54881
|
+
{label: "Urgencia", value: "urgent"}
|
|
54882
|
+
],
|
|
54883
|
+
value: {path: "/data/serviceType"},
|
|
54884
|
+
action: {event: {name: "service_selected", context: {service: {path: "/data/serviceType"}}}}
|
|
54885
|
+
}
|
|
54886
|
+
]
|
|
54887
|
+
\`\`\`
|
|
54888
|
+
|
|
54889
|
+
## Mejores Pr\xE1cticas
|
|
54890
|
+
|
|
54891
|
+
- Usar Tabs para wizards multi-paso
|
|
54892
|
+
- Usar Modal para confirmaciones antes de acciones cr\xEDticas
|
|
54893
|
+
- Usar ChoicePicker con \`variant: "mutuallyExclusive"\` para selecci\xF3n \xFAnica
|
|
54894
|
+
- Mostrar indicador de progreso (paso X de Y)
|
|
54895
|
+
- Actualizar data model despu\xE9s de cada acci\xF3n del usuario
|
|
54896
|
+
- Usar \`a2ui_update_components\` para cambiar la UI entre pasos
|
|
54897
|
+
- Agregar validaci\xF3n con \`checks\` en TextField
|
|
54898
|
+
- Mantener el estado del flujo en el data model (\`/data/step\`, \`/data/serviceType\`, etc.)
|
|
54899
|
+
- Eliminar surfaces con \`a2ui_delete_surface\` al completar o cancelar`
|
|
53924
54900
|
},
|
|
53925
54901
|
{
|
|
53926
54902
|
name: "canvas_interact",
|
|
@@ -54003,73 +54979,81 @@ canvas_ask({
|
|
|
54003
54979
|
`
|
|
54004
54980
|
},
|
|
54005
54981
|
{
|
|
54006
|
-
name: "
|
|
54007
|
-
description: `
|
|
54982
|
+
name: "canvas_report",
|
|
54983
|
+
description: `Display structured results to users using cards, lists, and progress indicators`,
|
|
54008
54984
|
category: "canvas",
|
|
54009
54985
|
version: "1.0.0",
|
|
54010
|
-
tools: ["
|
|
54011
|
-
triggers: ["
|
|
54986
|
+
tools: ["canvas_show_card", "canvas_show_list", "canvas_show_progress"],
|
|
54987
|
+
triggers: ["mostrame en el canvas", "show on canvas", "mostr\xE1 los resultados", "show results", "tarjeta informativa", "info card", "lista los resultados", "list results", "barra de progreso", "progress bar", "dashboard", "estado visual", "visual status"],
|
|
54012
54988
|
body: `
|
|
54013
|
-
# Canvas
|
|
54989
|
+
# Canvas Report Skill
|
|
54014
54990
|
|
|
54015
54991
|
## Cu\xE1ndo se Activa
|
|
54016
54992
|
|
|
54017
|
-
Para mostrar
|
|
54993
|
+
Para mostrar resultados estructurados visualmente en el canvas del usuario.
|
|
54018
54994
|
|
|
54019
54995
|
## Herramientas Disponibles
|
|
54020
54996
|
|
|
54021
54997
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54022
54998
|
|------|----------|---------------|
|
|
54023
|
-
| \`
|
|
54024
|
-
| \`
|
|
54025
|
-
| \`
|
|
54999
|
+
| \`canvas_show_card\` | Muestra informaci\xF3n estructurada | Resultados con items etiquetados |
|
|
55000
|
+
| \`canvas_show_list\` | Lista clave-valor | Configuraciones, datos simples |
|
|
55001
|
+
| \`canvas_show_progress\` | Barras de progreso | Estado de tasks m\xFAltiples |
|
|
54026
55002
|
|
|
54027
55003
|
## Workflow
|
|
54028
55004
|
|
|
54029
|
-
1. **
|
|
54030
|
-
2. **
|
|
54031
|
-
3. **
|
|
54032
|
-
4. **Refresh** \u2192 \`canvas_render({ updates })\` para cambios
|
|
55005
|
+
1. **Determinar formato** \u2192 Card vs List vs Progress
|
|
55006
|
+
2. **Renderizar** \u2192 \`canvas_show_*\` apropiado
|
|
55007
|
+
3. **Clear** \u2192 Si cambio de contexto significativo
|
|
54033
55008
|
|
|
54034
|
-
##
|
|
55009
|
+
## Formatos
|
|
54035
55010
|
|
|
55011
|
+
### Card
|
|
54036
55012
|
\`\`\`javascript
|
|
54037
|
-
|
|
54038
|
-
|
|
54039
|
-
|
|
54040
|
-
|
|
54041
|
-
|
|
54042
|
-
|
|
54043
|
-
|
|
55013
|
+
canvas_show_card({
|
|
55014
|
+
title: "Research Results",
|
|
55015
|
+
items: [
|
|
55016
|
+
{ label: "Trends Found", value: "7" },
|
|
55017
|
+
{ label: "Sources", value: "5 URLs" },
|
|
55018
|
+
{ label: "Time", value: "2.5 min" }
|
|
55019
|
+
]
|
|
54044
55020
|
})
|
|
54045
55021
|
|
|
54046
|
-
//
|
|
54047
|
-
canvas_show_card({
|
|
54048
|
-
|
|
55022
|
+
// Full-width card (ocupa todo el ancho del canvas):
|
|
55023
|
+
canvas_show_card({
|
|
55024
|
+
title: "Full Report",
|
|
55025
|
+
span: "full",
|
|
55026
|
+
items: [...]
|
|
55027
|
+
})
|
|
54049
55028
|
\`\`\`
|
|
54050
55029
|
|
|
54051
|
-
|
|
54052
|
-
|
|
54053
|
-
|
|
54054
|
-
|
|
54055
|
-
|
|
54056
|
-
|
|
54057
|
-
|
|
54058
|
-
|
|
54059
|
-
|
|
54060
|
-
|
|
55030
|
+
### List
|
|
55031
|
+
\`\`\`javascript
|
|
55032
|
+
canvas_show_list({
|
|
55033
|
+
items: {
|
|
55034
|
+
"Language": "Spanish",
|
|
55035
|
+
"Timezone": "UTC-3",
|
|
55036
|
+
"Channel": "Telegram"
|
|
55037
|
+
}
|
|
55038
|
+
})
|
|
55039
|
+
\`\`\`
|
|
54061
55040
|
|
|
54062
|
-
|
|
54063
|
-
|
|
54064
|
-
|
|
54065
|
-
|
|
55041
|
+
### Progress
|
|
55042
|
+
\`\`\`javascript
|
|
55043
|
+
canvas_show_progress({
|
|
55044
|
+
bars: [
|
|
55045
|
+
{ label: "Research", value: 100 },
|
|
55046
|
+
{ label: "Content", value: 60 },
|
|
55047
|
+
{ label: "Email", value: 0 }
|
|
55048
|
+
]
|
|
55049
|
+
})
|
|
55050
|
+
\`\`\`
|
|
54066
55051
|
|
|
54067
55052
|
## Errores a Evitar
|
|
54068
55053
|
|
|
54069
|
-
- \u274C
|
|
54070
|
-
- \u274C
|
|
54071
|
-
- \u274C No
|
|
54072
|
-
- \u274C Sin color coding para estados
|
|
55054
|
+
- \u274C Cards con demasiados items (>7)
|
|
55055
|
+
- \u274C Labels vagos sin contexto
|
|
55056
|
+
- \u274C No clear entre contextos diferentes
|
|
54073
55057
|
`
|
|
54074
55058
|
},
|
|
54075
55059
|
{
|
|
@@ -54270,314 +55254,244 @@ a2ui_update_data_model(surfaceId: "dash", path: "/", value: {metrics: {completio
|
|
|
54270
55254
|
- Eliminar surfaces al terminar para evitar memory leaks`
|
|
54271
55255
|
},
|
|
54272
55256
|
{
|
|
54273
|
-
name: "
|
|
54274
|
-
description: `
|
|
54275
|
-
category: "
|
|
55257
|
+
name: "voice_input",
|
|
55258
|
+
description: `Transcribe audio input to text using STT (Speech-to-Text) providers like Groq Whisper or OpenAI Whisper`,
|
|
55259
|
+
category: "voice",
|
|
54276
55260
|
version: "1.0.0",
|
|
54277
|
-
tools: ["
|
|
54278
|
-
triggers: ["
|
|
55261
|
+
tools: ["voice_transcribe"],
|
|
55262
|
+
triggers: ["transcrib\xED este audio", "transcribe audio", "convert\xED voz a texto", "convert voice to text", "qu\xE9 dice el audio", "what does audio say", "escuch\xE1 esto", "listen to this", "audio a texto", "audio to text", "reconocimiento de voz", "speech recognition", "nota de voz", "voice note"],
|
|
54279
55263
|
body: `
|
|
54280
|
-
#
|
|
55264
|
+
# Voice Input Skill
|
|
54281
55265
|
|
|
54282
55266
|
## Cu\xE1ndo se Activa
|
|
54283
55267
|
|
|
54284
|
-
|
|
54285
|
-
- Wizards paso a paso
|
|
54286
|
-
- Flujos de onboarding
|
|
54287
|
-
- Asistentes de reserva/configuraci\xF3n
|
|
54288
|
-
- Formularios con selections din\xE1micas
|
|
54289
|
-
- Interacciones con modales de confirmaci\xF3n
|
|
54290
|
-
- UIs que cambian seg\xFAn las acciones del usuario
|
|
55268
|
+
Esta skill se activa cuando el usuario env\xEDa audio y necesita transcripci\xF3n a texto: notas de voz, grabaciones, comandos de voz.
|
|
54291
55269
|
|
|
54292
|
-
##
|
|
55270
|
+
## Herramientas Disponibles
|
|
54293
55271
|
|
|
54294
55272
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54295
55273
|
|------|----------|---------------|
|
|
54296
|
-
| \`
|
|
54297
|
-
| \`a2ui_update_components\` | Env\xEDa/actualiza componentes | Para layout y cambios de UI |
|
|
54298
|
-
| \`a2ui_update_data_model\` | Actualiza datos | Para estado del workflow |
|
|
54299
|
-
| \`a2ui_delete_surface\` | Elimina la superficie | Al terminar flujo |
|
|
55274
|
+
| \`voice_transcribe\` | Convierte audio \u2192 texto | Transcripci\xF3n de cualquier audio |
|
|
54300
55275
|
|
|
54301
|
-
##
|
|
55276
|
+
## Workflow
|
|
54302
55277
|
|
|
54303
|
-
|
|
54304
|
-
|
|
54305
|
-
|
|
54306
|
-
|
|
54307
|
-
|
|
54308
|
-
|
|
54309
|
-
6. a2ui_update_components(...) // cambiar UI al siguiente paso
|
|
54310
|
-
7. ... repetir 4-6 seg\xFAn necesidad ...
|
|
54311
|
-
8. a2ui_delete_surface(surfaceId) // al terminar
|
|
54312
|
-
\`\`\`
|
|
55278
|
+
### Transcripci\xF3n
|
|
55279
|
+
\`\`\`javascript
|
|
55280
|
+
// 1. Recibir audio
|
|
55281
|
+
// - File upload
|
|
55282
|
+
// - Voice message (Telegram, WhatsApp)
|
|
55283
|
+
// - Stream en vivo
|
|
54313
55284
|
|
|
54314
|
-
|
|
55285
|
+
// 2. Transcribir
|
|
55286
|
+
const result = voice_transcribe({
|
|
55287
|
+
audio: audioBuffer,
|
|
55288
|
+
language: "es" // o "auto" para detectar
|
|
55289
|
+
})
|
|
54315
55290
|
|
|
54316
|
-
|
|
55291
|
+
// 3. Formatear
|
|
55292
|
+
// - Agregar puntuaci\xF3n
|
|
55293
|
+
// - Capitalizar
|
|
55294
|
+
// - Marcar speakers si hay m\xFAltiples
|
|
54317
55295
|
|
|
54318
|
-
|
|
54319
|
-
[
|
|
54320
|
-
{id: "root", component: "Column", children: ["step_indicator", "tabs"]},
|
|
54321
|
-
{id: "step_indicator", component: "Text", text: {path: "/stepLabel"}, variant: "caption"},
|
|
54322
|
-
{id: "tabs", component: "Tabs", tabs: [
|
|
54323
|
-
{title: "Servicio", child: "step1"},
|
|
54324
|
-
{title: "Fecha", child: "step2"},
|
|
54325
|
-
{title: "Confirmar", child: "step3"}
|
|
54326
|
-
]},
|
|
54327
|
-
{id: "step1", component: "Column", children: ["svc_label", "svc_picker"]},
|
|
54328
|
-
{id: "svc_label", component: "Text", text: "Seleccion\xE1 un servicio", variant: "h3"},
|
|
54329
|
-
{id: "svc_picker", component: "ChoicePicker", variant: "mutuallyExclusive", options: [...], value: {path: "/data/service"}},
|
|
54330
|
-
// ... m\xE1s pasos
|
|
54331
|
-
]
|
|
55296
|
+
// 4. Entregar resultado
|
|
54332
55297
|
\`\`\`
|
|
54333
55298
|
|
|
54334
|
-
|
|
55299
|
+
## Proveedores STT Soportados
|
|
54335
55300
|
|
|
54336
|
-
|
|
54337
|
-
|
|
54338
|
-
|
|
54339
|
-
|
|
54340
|
-
{id: "confirm_btn_text", component: "Text", text: "Confirmar Reserva"},
|
|
54341
|
-
{id: "confirm_dialog", component: "Column", children: ["confirm_msg", "confirm_yes", "confirm_no"]},
|
|
54342
|
-
{id: "confirm_msg", component: "Text", text: "\xBFConfirm\xE1s tu reserva?"},
|
|
54343
|
-
{id: "confirm_yes", component: "Button", child: "yes_text", variant: "primary", action: {event: {name: "confirm_booking", context: {service: {path: "/data/service"}}}}},
|
|
54344
|
-
{id: "yes_text", component: "Text", text: "S\xED, confirmar"},
|
|
54345
|
-
{id: "confirm_no", component: "Button", child: "no_text", variant: "borderless", action: {event: {name: "cancel"}}}},
|
|
54346
|
-
{id: "no_text", component: "Text", text: "Cancelar"}
|
|
54347
|
-
]
|
|
54348
|
-
\`\`\`
|
|
55301
|
+
| Provider | Modelos | Idiomas |
|
|
55302
|
+
|----------|---------|---------|
|
|
55303
|
+
| Groq | whisper-large-v3, turbo | Multi |
|
|
55304
|
+
| OpenAI | whisper-1 | Multi |
|
|
54349
55305
|
|
|
54350
|
-
|
|
55306
|
+
## Configuraci\xF3n por Canal
|
|
54351
55307
|
|
|
54352
|
-
|
|
54353
|
-
|
|
54354
|
-
{id: "service_picker", component: "ChoicePicker",
|
|
54355
|
-
variant: "mutuallyExclusive",
|
|
54356
|
-
options: [
|
|
54357
|
-
{label: "Consulta General", value: "general"},
|
|
54358
|
-
{label: "Especializada", value: "specialist"},
|
|
54359
|
-
{label: "Urgencia", value: "urgent"}
|
|
54360
|
-
],
|
|
54361
|
-
value: {path: "/data/serviceType"},
|
|
54362
|
-
action: {event: {name: "service_selected", context: {service: {path: "/data/serviceType"}}}}
|
|
54363
|
-
}
|
|
54364
|
-
]
|
|
54365
|
-
\`\`\`
|
|
55308
|
+
Cada canal puede configurar su proveedor STT preferido:
|
|
55309
|
+
- \`stt_provider\`: "groq-whisper" | "openai-whisper"
|
|
54366
55310
|
|
|
54367
55311
|
## Mejores Pr\xE1cticas
|
|
54368
55312
|
|
|
54369
|
-
-
|
|
54370
|
-
-
|
|
54371
|
-
-
|
|
54372
|
-
-
|
|
54373
|
-
|
|
54374
|
-
|
|
54375
|
-
|
|
54376
|
-
-
|
|
54377
|
-
-
|
|
55313
|
+
- Detectar idioma autom\xE1ticamente
|
|
55314
|
+
- Agregar puntuaci\xF3n para legibilidad
|
|
55315
|
+
- Marcar segmentos inaudibles
|
|
55316
|
+
- Preservar idioma original
|
|
55317
|
+
|
|
55318
|
+
## Errores a Evitar
|
|
55319
|
+
|
|
55320
|
+
- \u274C Traducir sin pedir (mantener idioma)
|
|
55321
|
+
- \u274C Omitir puntuaci\xF3n
|
|
55322
|
+
- \u274C No indicar baja confianza
|
|
55323
|
+
- \u274C Ignorar ruido de fondo que afecta calidad
|
|
55324
|
+
`
|
|
54378
55325
|
},
|
|
54379
55326
|
{
|
|
54380
|
-
name: "
|
|
54381
|
-
description: `
|
|
54382
|
-
category: "
|
|
55327
|
+
name: "voice_assistant",
|
|
55328
|
+
description: `Full voice-to-voice interaction: transcribe user speech, process request, and respond with synthesized speech`,
|
|
55329
|
+
category: "voice",
|
|
54383
55330
|
version: "1.0.0",
|
|
54384
|
-
tools: ["
|
|
54385
|
-
triggers: ["
|
|
55331
|
+
tools: ["voice_transcribe", "voice_speak"],
|
|
55332
|
+
triggers: ["modo voz", "voice mode", "asistente de voz", "voice assistant", "habl\xE1 conmigo", "talk to me", "interacci\xF3n por voz", "voice interaction", "respuesta hablada", "spoken response", "comando de voz", "voice command", "di\xE1logo por voz", "voice dialogue"],
|
|
54386
55333
|
body: `
|
|
54387
|
-
#
|
|
55334
|
+
# Voice Assistant Skill
|
|
54388
55335
|
|
|
54389
55336
|
## Cu\xE1ndo se Activa
|
|
54390
55337
|
|
|
54391
|
-
|
|
55338
|
+
Esta skill se activa para interacci\xF3n completa voz a voz: el usuario habla, el asistente procesa y responde con voz.
|
|
54392
55339
|
|
|
54393
55340
|
## Herramientas Disponibles
|
|
54394
55341
|
|
|
54395
55342
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54396
55343
|
|------|----------|---------------|
|
|
54397
|
-
| \`
|
|
54398
|
-
| \`
|
|
54399
|
-
| \`canvas_show_progress\` | Barras de progreso | Estado de tasks m\xFAltiples |
|
|
55344
|
+
| \`voice_transcribe\` | Audio \u2192 texto | Input del usuario |
|
|
55345
|
+
| \`voice_speak\` | Texto \u2192 audio | Respuesta del asistente |
|
|
54400
55346
|
|
|
54401
55347
|
## Workflow
|
|
54402
55348
|
|
|
54403
|
-
|
|
54404
|
-
2. **Renderizar** \u2192 \`canvas_show_*\` apropiado
|
|
54405
|
-
3. **Clear** \u2192 Si cambio de contexto significativo
|
|
54406
|
-
|
|
54407
|
-
## Formatos
|
|
54408
|
-
|
|
54409
|
-
### Card
|
|
55349
|
+
### Voice-to-Voice
|
|
54410
55350
|
\`\`\`javascript
|
|
54411
|
-
|
|
54412
|
-
|
|
54413
|
-
items: [
|
|
54414
|
-
{ label: "Trends Found", value: "7" },
|
|
54415
|
-
{ label: "Sources", value: "5 URLs" },
|
|
54416
|
-
{ label: "Time", value: "2.5 min" }
|
|
54417
|
-
]
|
|
54418
|
-
})
|
|
55351
|
+
// 1. Usuario habla
|
|
55352
|
+
const userAudio = receiveAudio()
|
|
54419
55353
|
|
|
54420
|
-
//
|
|
54421
|
-
|
|
54422
|
-
|
|
54423
|
-
|
|
54424
|
-
items: [...]
|
|
55354
|
+
// 2. Transcribir
|
|
55355
|
+
const userText = voice_transcribe({
|
|
55356
|
+
audio: userAudio,
|
|
55357
|
+
language: "auto"
|
|
54425
55358
|
})
|
|
54426
|
-
|
|
55359
|
+
// \u2192 "\xBFCu\xE1l es el clima hoy?"
|
|
54427
55360
|
|
|
54428
|
-
|
|
54429
|
-
|
|
54430
|
-
|
|
54431
|
-
|
|
54432
|
-
|
|
54433
|
-
"Timezone": "UTC-3",
|
|
54434
|
-
"Channel": "Telegram"
|
|
54435
|
-
}
|
|
54436
|
-
})
|
|
54437
|
-
\`\`\`
|
|
55361
|
+
// 3. Procesar request
|
|
55362
|
+
// - Entender intenci\xF3n
|
|
55363
|
+
// - Ejecutar acci\xF3n (ej. consultar API clima)
|
|
55364
|
+
// - Generar respuesta
|
|
55365
|
+
const responseText = "Hoy hay 25 grados y soleado en Buenos Aires"
|
|
54438
55366
|
|
|
54439
|
-
|
|
54440
|
-
|
|
54441
|
-
|
|
54442
|
-
|
|
54443
|
-
|
|
54444
|
-
{ label: "Content", value: 60 },
|
|
54445
|
-
{ label: "Email", value: 0 }
|
|
54446
|
-
]
|
|
55367
|
+
// 4. Sintetizar respuesta
|
|
55368
|
+
const responseAudio = voice_speak({
|
|
55369
|
+
text: responseText,
|
|
55370
|
+
voice_id: "eleven_flash_v2_5",
|
|
55371
|
+
language: "es"
|
|
54447
55372
|
})
|
|
54448
|
-
\`\`\`
|
|
54449
|
-
|
|
54450
|
-
## Errores a Evitar
|
|
54451
55373
|
|
|
54452
|
-
|
|
54453
|
-
|
|
54454
|
-
|
|
54455
|
-
`
|
|
54456
|
-
},
|
|
54457
|
-
{
|
|
54458
|
-
name: "meeting_transcription",
|
|
54459
|
-
description: `Transcribir reuniones en tiempo real y generar informes gerenciales con decisiones, action items y pr\xF3ximos pasos`,
|
|
54460
|
-
category: "meeting",
|
|
54461
|
-
version: "1.0.0",
|
|
54462
|
-
tools: ["meeting_start", "meeting_add_segment", "meeting_stop", "meeting_report", "office_escribir_docx", "notify", "report_progress"],
|
|
54463
|
-
triggers: ["transcribir reuni\xF3n", "iniciar transcripci\xF3n", "meeting transcription", "grabar reuni\xF3n", "iniciar reuni\xF3n", "start meeting", "detener reuni\xF3n", "stop meeting", "reporte de reuni\xF3n", "generar reporte reuni\xF3n", "informe de reuni\xF3n", "acta de reuni\xF3n", "transcripci\xF3n de reuni\xF3n", "meeting report"],
|
|
54464
|
-
body: `
|
|
54465
|
-
# Meeting Transcription Skill
|
|
54466
|
-
|
|
54467
|
-
## Cu\xE1ndo se Activa
|
|
54468
|
-
|
|
54469
|
-
Esta skill se activa para gesti\xF3n completa del ciclo de vida de una reuni\xF3n: inicio, transcripci\xF3n en tiempo real, detenci\xF3n y generaci\xF3n de informe gerencial.
|
|
55374
|
+
// 5. Enviar audio
|
|
55375
|
+
sendAudio(responseAudio)
|
|
55376
|
+
\`\`\`
|
|
54470
55377
|
|
|
54471
|
-
##
|
|
55378
|
+
## Casos de Uso
|
|
54472
55379
|
|
|
54473
|
-
|
|
|
54474
|
-
|
|
54475
|
-
|
|
|
54476
|
-
|
|
|
54477
|
-
|
|
|
54478
|
-
|
|
|
54479
|
-
| \`office_escribir_docx\` | Guarda el reporte como archivo Word | Al finalizar el an\xE1lisis |
|
|
54480
|
-
| \`notify\` | Env\xEDa mensajes en tiempo real al canal | Para mostrar transcripciones y el reporte |
|
|
54481
|
-
| \`report_progress\` | Muestra progreso en barra | Durante transcripci\xF3n larga |
|
|
55380
|
+
| Caso | Flujo |
|
|
55381
|
+
|------|-------|
|
|
55382
|
+
| Pregunta simple | Transcribe \u2192 responde \u2192 sintetiza |
|
|
55383
|
+
| Comando | Transcribe \u2192 ejecuta \u2192 confirma por voz |
|
|
55384
|
+
| Di\xE1logo | Mantener contexto entre exchanges |
|
|
55385
|
+
| Wake word | Escuchar "hey bee" \u2192 activar \u2192 procesar |
|
|
54482
55386
|
|
|
54483
|
-
##
|
|
55387
|
+
## Configuraci\xF3n
|
|
54484
55388
|
|
|
55389
|
+
### Wake Word
|
|
55390
|
+
\`\`\`json
|
|
55391
|
+
{
|
|
55392
|
+
"voice_wake_word": "hey bee",
|
|
55393
|
+
"voice_wake_enabled": true
|
|
55394
|
+
}
|
|
54485
55395
|
\`\`\`
|
|
54486
|
-
Usuario: "transcribir reuni\xF3n"
|
|
54487
|
-
\u2192 Agente pregunta t\xEDtulo
|
|
54488
|
-
\u2192 meeting_start(title) \u2192 session_id: "abc123"
|
|
54489
|
-
\u2192 Agente: "\u2705 Sesi\xF3n abc123 iniciada. Habla cuando quieras."
|
|
54490
|
-
|
|
54491
|
-
[Usuario graba audio en la UI]
|
|
54492
|
-
\u2192 meeting_add_segment(session_id, audio_base64)
|
|
54493
|
-
\u2192 notify: "[Speaker]: Texto transcrito..."
|
|
54494
|
-
|
|
54495
|
-
Usuario: "detener reuni\xF3n"
|
|
54496
|
-
\u2192 meeting_stop(session_id)
|
|
54497
|
-
\u2192 Agente: "\u23F9\uFE0F 47 segmentos transcritos. \xBFGenero el reporte?"
|
|
54498
55396
|
|
|
54499
|
-
|
|
54500
|
-
|
|
54501
|
-
|
|
54502
|
-
|
|
54503
|
-
|
|
54504
|
-
|
|
55397
|
+
### Canal Voice
|
|
55398
|
+
\`\`\`json
|
|
55399
|
+
{
|
|
55400
|
+
"voice_enabled": true,
|
|
55401
|
+
"tts_enabled": true,
|
|
55402
|
+
"stt_provider": "groq-whisper",
|
|
55403
|
+
"tts_provider": "elevenlabs",
|
|
55404
|
+
"tts_voice_id": "eleven_flash_v2_5"
|
|
55405
|
+
}
|
|
54505
55406
|
\`\`\`
|
|
54506
55407
|
|
|
54507
|
-
##
|
|
54508
|
-
|
|
54509
|
-
El informe generado incluye:
|
|
55408
|
+
## Mejores Pr\xE1cticas
|
|
54510
55409
|
|
|
54511
|
-
|
|
54512
|
-
|
|
54513
|
-
|
|
54514
|
-
|
|
54515
|
-
5. **Pr\xF3ximos Pasos** \u2014 Acciones inmediatas
|
|
54516
|
-
6. **Temas de Seguimiento** \u2014 Pendientes para futuras reuniones
|
|
55410
|
+
- Respuestas cortas y naturales (<60s)
|
|
55411
|
+
- Mantener contexto conversacional
|
|
55412
|
+
- Indicadores de procesamiento
|
|
55413
|
+
- Fallback a texto si falla voz
|
|
54517
55414
|
|
|
54518
|
-
##
|
|
55415
|
+
## Errores a Evitar
|
|
54519
55416
|
|
|
54520
|
-
-
|
|
54521
|
-
-
|
|
54522
|
-
-
|
|
54523
|
-
-
|
|
55417
|
+
- \u274C Respuestas muy largas para audio
|
|
55418
|
+
- \u274C Perder contexto entre exchanges
|
|
55419
|
+
- \u274C No indicar que est\xE1 procesando
|
|
55420
|
+
- \u274C No tener fallback si falla TTS/STT
|
|
54524
55421
|
`
|
|
54525
55422
|
},
|
|
54526
55423
|
{
|
|
54527
|
-
name: "
|
|
54528
|
-
description: `
|
|
54529
|
-
category: "
|
|
55424
|
+
name: "voice_output",
|
|
55425
|
+
description: `Convert text to synthesized speech using TTS (Text-to-Speech) providers like ElevenLabs, OpenAI TTS, or Gemini TTS`,
|
|
55426
|
+
category: "voice",
|
|
54530
55427
|
version: "1.0.0",
|
|
54531
|
-
tools: ["
|
|
54532
|
-
triggers: ["
|
|
55428
|
+
tools: ["voice_speak"],
|
|
55429
|
+
triggers: ["le\xE9 esto en voz alta", "read this aloud", "convert\xED a voz", "convert to speech", "habl\xE1 este texto", "speak this text", "texto a voz", "text to speech", "gener\xE1 audio", "generate audio", "s\xEDntesis de voz", "voice synthesis", "escuch\xE1 la respuesta", "listen to response"],
|
|
54533
55430
|
body: `
|
|
54534
|
-
#
|
|
55431
|
+
# Voice Output Skill
|
|
54535
55432
|
|
|
54536
55433
|
## Cu\xE1ndo se Activa
|
|
54537
55434
|
|
|
54538
|
-
Esta skill se activa cuando el usuario necesita
|
|
55435
|
+
Esta skill se activa cuando el usuario necesita convertir texto a voz: leer respuestas, generar audio, s\xEDntesis de voz.
|
|
54539
55436
|
|
|
54540
55437
|
## Herramientas Disponibles
|
|
54541
55438
|
|
|
54542
55439
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54543
55440
|
|------|----------|---------------|
|
|
54544
|
-
| \`
|
|
55441
|
+
| \`voice_speak\` | Convierte texto \u2192 audio | S\xEDntesis de voz |
|
|
54545
55442
|
|
|
54546
|
-
##
|
|
55443
|
+
## Workflow
|
|
54547
55444
|
|
|
54548
|
-
-
|
|
54549
|
-
|
|
54550
|
-
|
|
54551
|
-
|
|
54552
|
-
- \`query_params\` (opcional): par\xE1metros de query que se codificar\xE1n autom\xE1ticamente en la URL
|
|
54553
|
-
- \`timeout_ms\` (opcional): timeout en ms. Default: 30000. M\xE1x: 120000
|
|
55445
|
+
### Text-to-Speech
|
|
55446
|
+
\`\`\`javascript
|
|
55447
|
+
// 1. Recibir texto
|
|
55448
|
+
const text = "Hola, \xBFc\xF3mo est\xE1s?"
|
|
54554
55449
|
|
|
54555
|
-
|
|
55450
|
+
// 2. Preprocesar
|
|
55451
|
+
// - Expandir n\xFAmeros: "5" \u2192 "cinco"
|
|
55452
|
+
// - Expandir fechas: "01/01" \u2192 "primero de enero"
|
|
55453
|
+
// - Expandir abbreviaturas: "Dr." \u2192 "Doctor"
|
|
54556
55454
|
|
|
54557
|
-
|
|
54558
|
-
|
|
55455
|
+
// 3. Sintetizar
|
|
55456
|
+
const audio = voice_speak({
|
|
55457
|
+
text: optimizedText,
|
|
55458
|
+
voice_id: "eleven_flash_v2_5", // o configured voice
|
|
55459
|
+
language: "es"
|
|
55460
|
+
})
|
|
54559
55461
|
|
|
54560
|
-
|
|
55462
|
+
// 4. Entregar audio
|
|
55463
|
+
// - Enviar como archivo
|
|
55464
|
+
// - Streaming si el canal lo soporta
|
|
55465
|
+
\`\`\`
|
|
54561
55466
|
|
|
54562
|
-
|
|
54563
|
-
|
|
54564
|
-
|
|
54565
|
-
|
|
55467
|
+
## Proveedores TTS Soportados
|
|
55468
|
+
|
|
55469
|
+
| Provider | Modelos | Voces |
|
|
55470
|
+
|----------|---------|-------|
|
|
55471
|
+
| ElevenLabs | Flash V2.5, Turbo V2.5, Multilingual V2, V3 | 1000+ |
|
|
55472
|
+
| OpenAI | tts-1, tts-1-hd, gpt-4o-mini-tts | 6+ |
|
|
55473
|
+
| Gemini | 2.5 Flash TTS, 2.5 Pro TTS | Multi |
|
|
55474
|
+
| Qwen | Qwen TTS Flash, Instruct | Multi |
|
|
55475
|
+
|
|
55476
|
+
## Configuraci\xF3n por Canal
|
|
55477
|
+
|
|
55478
|
+
Cada canal configura su proveedor TTS:
|
|
55479
|
+
- \`tts_provider\`: "elevenlabs" | "openai-tts" | "gemini-tts"
|
|
55480
|
+
- \`tts_voice_id\`: ID espec\xEDfico de voz (ej. ElevenLabs voice ID)
|
|
54566
55481
|
|
|
54567
55482
|
## Mejores Pr\xE1cticas
|
|
54568
55483
|
|
|
54569
|
-
-
|
|
54570
|
-
- Usar
|
|
54571
|
-
-
|
|
54572
|
-
-
|
|
54573
|
-
- Para errores 4xx, revisar: auth, formato del body, campos requeridos, rate limits
|
|
55484
|
+
- Preprocesar texto para naturalidad
|
|
55485
|
+
- Usar voz configurada por usuario
|
|
55486
|
+
- Cachear respuestas frecuentes
|
|
55487
|
+
- Split de textos largos
|
|
54574
55488
|
|
|
54575
55489
|
## Errores a Evitar
|
|
54576
55490
|
|
|
54577
|
-
- \u274C
|
|
54578
|
-
- \u274C
|
|
54579
|
-
- \u274C
|
|
54580
|
-
- \u274C
|
|
55491
|
+
- \u274C Enviar texto crudo sin preprocesar
|
|
55492
|
+
- \u274C Ignorar preferencia de voz
|
|
55493
|
+
- \u274C No manejar l\xEDmites de longitud
|
|
55494
|
+
- \u274C No cachear (costo API)
|
|
54581
55495
|
`
|
|
54582
55496
|
},
|
|
54583
55497
|
{
|
|
@@ -54719,71 +55633,6 @@ const result = task_status({ task_id })
|
|
|
54719
55633
|
- \u274C No monitorear ejecuci\xF3n larga
|
|
54720
55634
|
- \u274C Ignorar errores del subagente
|
|
54721
55635
|
- \u274C No verificar que el c\xF3digo cumple requisitos
|
|
54722
|
-
`
|
|
54723
|
-
},
|
|
54724
|
-
{
|
|
54725
|
-
name: "memory_manager",
|
|
54726
|
-
description: `Complete management of persistent memory including write, read, search, list, and delete operations`,
|
|
54727
|
-
category: "agents",
|
|
54728
|
-
version: "1.0.0",
|
|
54729
|
-
tools: ["memory_write", "memory_read", "memory_list", "memory_search", "memory_delete"],
|
|
54730
|
-
triggers: ["guard\xE1 en memoria", "save to memory", "record\xE1 esto", "remember this", "le\xE9 la memoria", "read memory", "qu\xE9 hay en memoria", "what's in memory", "busc\xE1 en memoria", "search memory", "lista las memorias", "list memories", "elimin\xE1 de memoria", "delete from memory", "preferencias", "preferences", "datos persistentes", "persistent data"],
|
|
54731
|
-
body: `
|
|
54732
|
-
# Memory Manager Skill
|
|
54733
|
-
|
|
54734
|
-
## Cu\xE1ndo se Activa
|
|
54735
|
-
|
|
54736
|
-
Para guardar, recuperar, buscar, listar o eliminar informaci\xF3n persistente entre sesiones.
|
|
54737
|
-
|
|
54738
|
-
## Herramientas Disponibles
|
|
54739
|
-
|
|
54740
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
54741
|
-
|------|----------|---------------|
|
|
54742
|
-
| \`memory_write\` | Almacena con t\xEDtulo \xFAnico | Guardar preferencias, datos |
|
|
54743
|
-
| \`memory_read\` | Recupera por t\xEDtulo exacto | Cuando conoc\xE9s el t\xEDtulo |
|
|
54744
|
-
| \`memory_list\` | Lista todos los t\xEDtulos | Explorar qu\xE9 hay guardado |
|
|
54745
|
-
| \`memory_search\` | Busca por keywords | Cuando no record\xE1s t\xEDtulo exacto |
|
|
54746
|
-
| \`memory_delete\` | Elimina entrada | Limpiar datos obsoletos |
|
|
54747
|
-
|
|
54748
|
-
## Workflow
|
|
54749
|
-
|
|
54750
|
-
### Write
|
|
54751
|
-
\`\`\`javascript
|
|
54752
|
-
memory_write({
|
|
54753
|
-
title: "Preferencias de Desarrollo",
|
|
54754
|
-
content: "TypeScript, VS Code, Prettier single quotes"
|
|
54755
|
-
})
|
|
54756
|
-
\`\`\`
|
|
54757
|
-
|
|
54758
|
-
### Read/Search
|
|
54759
|
-
\`\`\`javascript
|
|
54760
|
-
memory_read({ title: "Preferencias" }) // T\xEDtulo exacto
|
|
54761
|
-
memory_search({ query: "preferencias" }) // Fuzzy match
|
|
54762
|
-
\`\`\`
|
|
54763
|
-
|
|
54764
|
-
### List
|
|
54765
|
-
\`\`\`javascript
|
|
54766
|
-
memory_list({}) // Todos los t\xEDtulos
|
|
54767
|
-
\`\`\`
|
|
54768
|
-
|
|
54769
|
-
### Delete
|
|
54770
|
-
\`\`\`javascript
|
|
54771
|
-
memory_delete({ title: "Datos Temporales" })
|
|
54772
|
-
\`\`\`
|
|
54773
|
-
|
|
54774
|
-
## Mejores Pr\xE1cticas
|
|
54775
|
-
|
|
54776
|
-
- T\xEDtulos descriptivos y \xFAnicos
|
|
54777
|
-
- Agrupar datos relacionados en misma entrada
|
|
54778
|
-
- Confirmar antes de sobrescribir
|
|
54779
|
-
- No guardar datos sensibles
|
|
54780
|
-
|
|
54781
|
-
## Errores a Evitar
|
|
54782
|
-
|
|
54783
|
-
- \u274C Datos sensibles (passwords, API keys)
|
|
54784
|
-
- \u274C T\xEDtulos gen\xE9ricos ("Config", "Datos")
|
|
54785
|
-
- \u274C Sobrescribir sin confirmar
|
|
54786
|
-
- \u274C Entradas gigantes (split por tema)
|
|
54787
55636
|
`
|
|
54788
55637
|
},
|
|
54789
55638
|
{
|
|
@@ -54953,241 +55802,137 @@ bus_read() \u2192 [{ from: "writer", content: "Need research results" }]
|
|
|
54953
55802
|
`
|
|
54954
55803
|
},
|
|
54955
55804
|
{
|
|
54956
|
-
name: "
|
|
54957
|
-
description: `
|
|
54958
|
-
category: "
|
|
54959
|
-
version: "1.2.0",
|
|
54960
|
-
tools: ["search_knowledge"],
|
|
54961
|
-
triggers: ["c\xF3mo busco herramientas", "c\xF3mo encuentro skills", "how to find tools", "search knowledge", "discovery", "buscar en la base", "encontrar herramientas"],
|
|
54962
|
-
body: `
|
|
54963
|
-
# busqueda_fts5 \u2014 Sistema de Discovery
|
|
54964
|
-
|
|
54965
|
-
Arranc\xE1s con solo 4 herramientas. Todo lo dem\xE1s se descubre con **search_knowledge**.
|
|
54966
|
-
|
|
54967
|
-
## Regla de oro: UNA PALABRA, busca TODO
|
|
54968
|
-
|
|
54969
|
-
\`\`\`
|
|
54970
|
-
search_knowledge(query="email")
|
|
54971
|
-
\`\`\`
|
|
54972
|
-
|
|
54973
|
-
Eso solo \u2014 sin type, sin frases largas \u2014 devuelve tools, skills, MCP y playbook relacionados con "email".
|
|
54974
|
-
|
|
54975
|
-
**NO hagas esto:** \`search_knowledge(type="tools", query="enviar correo electr\xF3nico")\` \u2014 AND entre palabras no encuentra nada.
|
|
54976
|
-
|
|
54977
|
-
**S\xCD hagas esto:** \`search_knowledge(query="email")\` \u2014 encuentra todo lo relacionado.
|
|
54978
|
-
|
|
54979
|
-
## Cu\xE1ndo especificar type
|
|
54980
|
-
|
|
54981
|
-
Solo si quer\xE9s filtrar resultados que ya son muchos:
|
|
54982
|
-
|
|
54983
|
-
\`\`\`
|
|
54984
|
-
search_knowledge(query="email", type="mcp") \u2192 solo herramientas externas de email
|
|
54985
|
-
search_knowledge(query="email", type="tools") \u2192 solo herramientas nativas de email
|
|
54986
|
-
\`\`\`
|
|
54987
|
-
|
|
54988
|
-
Por defecto type="all" \u2014 no hace falta especificarlo.
|
|
54989
|
-
|
|
54990
|
-
## Regla de prioridad
|
|
54991
|
-
|
|
54992
|
-
**Prefer\xED herramientas nativas sobre MCP** cuando ambas sirven.
|
|
54993
|
-
- Nativas: m\xE1s r\xE1pidas, sin red, siempre disponibles
|
|
54994
|
-
- MCP: cuando no hay equivalente nativo
|
|
54995
|
-
|
|
54996
|
-
## Flujo de uso
|
|
54997
|
-
|
|
54998
|
-
1. Identific\xE1 la palabra clave de lo que necesit\xE1s
|
|
54999
|
-
2. \`search_knowledge(query="<palabra>")\` \u2192 resultados de todos los tipos
|
|
55000
|
-
3. Las tools encontradas se inyectan autom\xE1ticamente en tu contexto
|
|
55001
|
-
4. Us\xE1s las tools en el siguiente paso
|
|
55002
|
-
|
|
55003
|
-
---
|
|
55004
|
-
|
|
55005
|
-
## Ejemplos
|
|
55006
|
-
|
|
55007
|
-
\`\`\`
|
|
55008
|
-
search_knowledge(query="pdf") \u2192 tools para leer/escribir PDFs
|
|
55009
|
-
search_knowledge(query="browser") \u2192 tools de navegaci\xF3n web
|
|
55010
|
-
search_knowledge(query="github") \u2192 tools MCP de GitHub si est\xE1n configuradas
|
|
55011
|
-
search_knowledge(query="calendar") \u2192 tools de Google Calendar
|
|
55012
|
-
search_knowledge(query="canvas") \u2192 skills de visualizaci\xF3n
|
|
55013
|
-
search_knowledge(query="slack") \u2192 tools de Slack si est\xE1n configuradas
|
|
55014
|
-
\`\`\`
|
|
55015
|
-
`
|
|
55016
|
-
},
|
|
55017
|
-
{
|
|
55018
|
-
name: "web_monitor",
|
|
55019
|
-
description: `Monitor changes in web sources and track updates over time with persistent memory`,
|
|
55020
|
-
category: "web",
|
|
55805
|
+
name: "memory_manager",
|
|
55806
|
+
description: `Complete management of persistent memory including write, read, search, list, and delete operations`,
|
|
55807
|
+
category: "agents",
|
|
55021
55808
|
version: "1.0.0",
|
|
55022
|
-
tools: ["
|
|
55023
|
-
triggers: ["
|
|
55809
|
+
tools: ["memory_write", "memory_read", "memory_list", "memory_search", "memory_delete"],
|
|
55810
|
+
triggers: ["guard\xE1 en memoria", "save to memory", "record\xE1 esto", "remember this", "le\xE9 la memoria", "read memory", "qu\xE9 hay en memoria", "what's in memory", "busc\xE1 en memoria", "search memory", "lista las memorias", "list memories", "elimin\xE1 de memoria", "delete from memory", "preferencias", "preferences", "datos persistentes", "persistent data"],
|
|
55024
55811
|
body: `
|
|
55025
|
-
#
|
|
55812
|
+
# Memory Manager Skill
|
|
55026
55813
|
|
|
55027
55814
|
## Cu\xE1ndo se Activa
|
|
55028
55815
|
|
|
55029
|
-
|
|
55030
|
-
- Monitorear cambios en una URL espec\xEDfica
|
|
55031
|
-
- Recibir notificaciones de actualizaciones
|
|
55032
|
-
- Seguir novedades sobre un tema
|
|
55033
|
-
- Trackear evoluci\xF3n de contenido
|
|
55816
|
+
Para guardar, recuperar, buscar, listar o eliminar informaci\xF3n persistente entre sesiones.
|
|
55034
55817
|
|
|
55035
55818
|
## Herramientas Disponibles
|
|
55036
55819
|
|
|
55037
55820
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55038
55821
|
|------|----------|---------------|
|
|
55039
|
-
| \`
|
|
55040
|
-
| \`
|
|
55041
|
-
| \`
|
|
55042
|
-
| \`
|
|
55822
|
+
| \`memory_write\` | Almacena con t\xEDtulo \xFAnico | Guardar preferencias, datos |
|
|
55823
|
+
| \`memory_read\` | Recupera por t\xEDtulo exacto | Cuando conoc\xE9s el t\xEDtulo |
|
|
55824
|
+
| \`memory_list\` | Lista todos los t\xEDtulos | Explorar qu\xE9 hay guardado |
|
|
55825
|
+
| \`memory_search\` | Busca por keywords | Cuando no record\xE1s t\xEDtulo exacto |
|
|
55826
|
+
| \`memory_delete\` | Elimina entrada | Limpiar datos obsoletos |
|
|
55043
55827
|
|
|
55044
55828
|
## Workflow
|
|
55045
55829
|
|
|
55046
|
-
|
|
55047
|
-
|
|
55048
|
-
|
|
55049
|
-
|
|
55050
|
-
|
|
55051
|
-
|
|
55052
|
-
|
|
55053
|
-
- Notificar solo cambios significativos
|
|
55054
|
-
- Para monitoreo peri\xF3dico, combinar con \`cron.create\`
|
|
55055
|
-
|
|
55056
|
-
## Errores a Evitar
|
|
55057
|
-
|
|
55058
|
-
- \u274C No almacenar baseline inicial
|
|
55059
|
-
- \u274C Notificar por cambios triviales
|
|
55060
|
-
- \u274C No actualizar timestamp de baseline
|
|
55061
|
-
`
|
|
55062
|
-
},
|
|
55063
|
-
{
|
|
55064
|
-
name: "web_research",
|
|
55065
|
-
description: `Search and synthesize information from multiple web sources into structured reports`,
|
|
55066
|
-
category: "web",
|
|
55067
|
-
version: "1.0.0",
|
|
55068
|
-
tools: ["web_search", "web_fetch"],
|
|
55069
|
-
triggers: ["investig\xE1 sobre", "research", "busc\xE1 informaci\xF3n de", "find information about", "qu\xE9 es", "what is", "explicame", "explain", "\xFAltimos avances", "latest advances", "tendencias de", "trends in", "informaci\xF3n actualizada", "current information"],
|
|
55070
|
-
body: `
|
|
55071
|
-
# Web Research Skill
|
|
55072
|
-
|
|
55073
|
-
## Cu\xE1ndo se Activa
|
|
55074
|
-
|
|
55075
|
-
Esta skill se activa cuando el usuario necesita informaci\xF3n actualizada de internet, verificar datos, o investigar temas espec\xEDficos.
|
|
55076
|
-
|
|
55077
|
-
## Herramientas Disponibles
|
|
55830
|
+
### Write
|
|
55831
|
+
\`\`\`javascript
|
|
55832
|
+
memory_write({
|
|
55833
|
+
title: "Preferencias de Desarrollo",
|
|
55834
|
+
content: "TypeScript, VS Code, Prettier single quotes"
|
|
55835
|
+
})
|
|
55836
|
+
\`\`\`
|
|
55078
55837
|
|
|
55079
|
-
|
|
55080
|
-
|
|
55081
|
-
|
|
55082
|
-
|
|
55838
|
+
### Read/Search
|
|
55839
|
+
\`\`\`javascript
|
|
55840
|
+
memory_read({ title: "Preferencias" }) // T\xEDtulo exacto
|
|
55841
|
+
memory_search({ query: "preferencias" }) // Fuzzy match
|
|
55842
|
+
\`\`\`
|
|
55083
55843
|
|
|
55084
|
-
|
|
55844
|
+
### List
|
|
55845
|
+
\`\`\`javascript
|
|
55846
|
+
memory_list({}) // Todos los t\xEDtulos
|
|
55847
|
+
\`\`\`
|
|
55085
55848
|
|
|
55086
|
-
|
|
55087
|
-
|
|
55088
|
-
|
|
55089
|
-
|
|
55849
|
+
### Delete
|
|
55850
|
+
\`\`\`javascript
|
|
55851
|
+
memory_delete({ title: "Datos Temporales" })
|
|
55852
|
+
\`\`\`
|
|
55090
55853
|
|
|
55091
55854
|
## Mejores Pr\xE1cticas
|
|
55092
55855
|
|
|
55093
|
-
-
|
|
55094
|
-
-
|
|
55095
|
-
-
|
|
55096
|
-
-
|
|
55856
|
+
- T\xEDtulos descriptivos y \xFAnicos
|
|
55857
|
+
- Agrupar datos relacionados en misma entrada
|
|
55858
|
+
- Confirmar antes de sobrescribir
|
|
55859
|
+
- No guardar datos sensibles
|
|
55097
55860
|
|
|
55098
55861
|
## Errores a Evitar
|
|
55099
55862
|
|
|
55100
|
-
- \u274C
|
|
55101
|
-
- \u274C
|
|
55102
|
-
- \u274C
|
|
55103
|
-
- \u274C
|
|
55863
|
+
- \u274C Datos sensibles (passwords, API keys)
|
|
55864
|
+
- \u274C T\xEDtulos gen\xE9ricos ("Config", "Datos")
|
|
55865
|
+
- \u274C Sobrescribir sin confirmar
|
|
55866
|
+
- \u274C Entradas gigantes (split por tema)
|
|
55104
55867
|
`
|
|
55105
55868
|
},
|
|
55106
55869
|
{
|
|
55107
|
-
name: "
|
|
55108
|
-
description: `
|
|
55109
|
-
category: "
|
|
55870
|
+
name: "meeting_transcription",
|
|
55871
|
+
description: `Transcribir reuniones en tiempo real y generar informes gerenciales con decisiones, action items y pr\xF3ximos pasos`,
|
|
55872
|
+
category: "meeting",
|
|
55110
55873
|
version: "1.0.0",
|
|
55111
|
-
tools: ["
|
|
55112
|
-
triggers: ["
|
|
55874
|
+
tools: ["meeting_start", "meeting_add_segment", "meeting_stop", "meeting_report", "office_escribir_docx", "notify", "report_progress"],
|
|
55875
|
+
triggers: ["transcribir reuni\xF3n", "iniciar transcripci\xF3n", "meeting transcription", "grabar reuni\xF3n", "iniciar reuni\xF3n", "start meeting", "detener reuni\xF3n", "stop meeting", "reporte de reuni\xF3n", "generar reporte reuni\xF3n", "informe de reuni\xF3n", "acta de reuni\xF3n", "transcripci\xF3n de reuni\xF3n", "meeting report"],
|
|
55113
55876
|
body: `
|
|
55114
|
-
#
|
|
55877
|
+
# Meeting Transcription Skill
|
|
55115
55878
|
|
|
55116
55879
|
## Cu\xE1ndo se Activa
|
|
55117
55880
|
|
|
55118
|
-
Esta skill se activa para
|
|
55881
|
+
Esta skill se activa para gesti\xF3n completa del ciclo de vida de una reuni\xF3n: inicio, transcripci\xF3n en tiempo real, detenci\xF3n y generaci\xF3n de informe gerencial.
|
|
55119
55882
|
|
|
55120
55883
|
## Herramientas Disponibles
|
|
55121
55884
|
|
|
55122
55885
|
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55123
55886
|
|------|----------|---------------|
|
|
55124
|
-
| \`
|
|
55125
|
-
| \`
|
|
55126
|
-
| \`
|
|
55127
|
-
| \`
|
|
55128
|
-
|
|
55129
|
-
|
|
55130
|
-
|
|
55131
|
-
1. **Navegar** \u2192 URL inicial
|
|
55132
|
-
2. **Interactuar** \u2192 click/type seg\xFAn flujo
|
|
55133
|
-
3. **Verificar** \u2192 screenshot despu\xE9s de acciones cr\xEDticas
|
|
55134
|
-
4. **Repetir** \u2192 para flujos multi-paso
|
|
55135
|
-
|
|
55136
|
-
## Mejores Pr\xE1cticas
|
|
55137
|
-
|
|
55138
|
-
- Selectores estables (IDs > classes > XPath)
|
|
55139
|
-
- Esperar carga despu\xE9s de navegaci\xF3n
|
|
55140
|
-
- Verificar estado visual con screenshots
|
|
55141
|
-
- Manejar errores de elementos no encontrados
|
|
55142
|
-
|
|
55143
|
-
## Errores a Evitar
|
|
55144
|
-
|
|
55145
|
-
- \u274C Selectores fr\xE1giles que cambian
|
|
55146
|
-
- \u274C No esperar carga de p\xE1gina
|
|
55147
|
-
- \u274C Ignorar errores de elementos
|
|
55148
|
-
- \u274C No verificar estado despu\xE9s de acciones
|
|
55149
|
-
`
|
|
55150
|
-
},
|
|
55151
|
-
{
|
|
55152
|
-
name: "browser_scrape",
|
|
55153
|
-
description: `Navigate to web pages and capture rendered content including screenshots for dynamic sites`,
|
|
55154
|
-
category: "web",
|
|
55155
|
-
version: "1.0.0",
|
|
55156
|
-
tools: ["browser_navigate", "browser_screenshot", "web_fetch"],
|
|
55157
|
-
triggers: ["captur\xE1 el contenido", "scrape content", "obten\xE9 la p\xE1gina renderizada", "get rendered page", "sitios din\xE1micos", "dynamic sites", "web con javascript", "javascript websites", "tom\xE1 screenshot y contenido", "screenshot and content"],
|
|
55158
|
-
body: `
|
|
55159
|
-
# Browser Scrape Skill
|
|
55887
|
+
| \`meeting_start\` | Crea una sesi\xF3n en DB \u2192 devuelve session_id | Al iniciar la reuni\xF3n |
|
|
55888
|
+
| \`meeting_add_segment\` | Transcribe un chunk de audio y lo persiste | Por cada audio recibido |
|
|
55889
|
+
| \`meeting_stop\` | Marca la sesi\xF3n como detenida | Cuando termina la reuni\xF3n |
|
|
55890
|
+
| \`meeting_report\` | Lee todos los segmentos y arma el transcript | Para generar el reporte |
|
|
55891
|
+
| \`office_escribir_docx\` | Guarda el reporte como archivo Word | Al finalizar el an\xE1lisis |
|
|
55892
|
+
| \`notify\` | Env\xEDa mensajes en tiempo real al canal | Para mostrar transcripciones y el reporte |
|
|
55893
|
+
| \`report_progress\` | Muestra progreso en barra | Durante transcripci\xF3n larga |
|
|
55160
55894
|
|
|
55161
|
-
##
|
|
55895
|
+
## Workflow Completo
|
|
55162
55896
|
|
|
55163
|
-
|
|
55897
|
+
\`\`\`
|
|
55898
|
+
Usuario: "transcribir reuni\xF3n"
|
|
55899
|
+
\u2192 Agente pregunta t\xEDtulo
|
|
55900
|
+
\u2192 meeting_start(title) \u2192 session_id: "abc123"
|
|
55901
|
+
\u2192 Agente: "\u2705 Sesi\xF3n abc123 iniciada. Habla cuando quieras."
|
|
55164
55902
|
|
|
55165
|
-
|
|
55903
|
+
[Usuario graba audio en la UI]
|
|
55904
|
+
\u2192 meeting_add_segment(session_id, audio_base64)
|
|
55905
|
+
\u2192 notify: "[Speaker]: Texto transcrito..."
|
|
55166
55906
|
|
|
55167
|
-
|
|
55168
|
-
|
|
55169
|
-
|
|
55170
|
-
| \`browser_screenshot\` | Captura estado visual | Evidencia de contenido renderizado |
|
|
55171
|
-
| \`web_fetch\` | Extrae texto como markdown | Contenido textual de p\xE1gina renderizada |
|
|
55907
|
+
Usuario: "detener reuni\xF3n"
|
|
55908
|
+
\u2192 meeting_stop(session_id)
|
|
55909
|
+
\u2192 Agente: "\u23F9\uFE0F 47 segmentos transcritos. \xBFGenero el reporte?"
|
|
55172
55910
|
|
|
55173
|
-
|
|
55911
|
+
Usuario: "s\xED"
|
|
55912
|
+
\u2192 meeting_report(session_id) \u2192 transcript completo
|
|
55913
|
+
\u2192 LLM analiza \u2192 secciones estructuradas
|
|
55914
|
+
\u2192 office_escribir_docx \u2192 informe_reunion_abc123.docx
|
|
55915
|
+
\u2192 notify: [Markdown del informe completo]
|
|
55916
|
+
\u2192 Agente: "\u2705 DOCX guardado en workspace."
|
|
55917
|
+
\`\`\`
|
|
55174
55918
|
|
|
55175
|
-
|
|
55176
|
-
2. **Capturar visual** \u2192 \`browser_screenshot()\`
|
|
55177
|
-
3. **Extraer texto** \u2192 \`web_fetch()\`
|
|
55178
|
-
4. **Combinar** \u2192 screenshot + texto para scrape completo
|
|
55919
|
+
## Formato del Informe Gerencial
|
|
55179
55920
|
|
|
55180
|
-
|
|
55921
|
+
El informe generado incluye:
|
|
55181
55922
|
|
|
55182
|
-
|
|
55183
|
-
|
|
55184
|
-
|
|
55923
|
+
1. **Resumen Ejecutivo** \u2014 Captura la esencia en 3-5 oraciones
|
|
55924
|
+
2. **Participantes** \u2014 Detectados autom\xE1ticamente del transcript
|
|
55925
|
+
3. **Decisiones Tomadas** \u2014 Lista numerada de cada decisi\xF3n
|
|
55926
|
+
4. **Action Items** \u2014 Tabla con Tarea / Responsable / Fecha
|
|
55927
|
+
5. **Pr\xF3ximos Pasos** \u2014 Acciones inmediatas
|
|
55928
|
+
6. **Temas de Seguimiento** \u2014 Pendientes para futuras reuniones
|
|
55185
55929
|
|
|
55186
|
-
##
|
|
55930
|
+
## Consideraciones
|
|
55187
55931
|
|
|
55188
|
-
-
|
|
55189
|
-
-
|
|
55190
|
-
-
|
|
55932
|
+
- El informe se entrega en dos formatos: **Markdown en chat** + **DOCX descargable**
|
|
55933
|
+
- El idioma del informe es siempre **espa\xF1ol**
|
|
55934
|
+
- La latencia de transcripci\xF3n es ~4s por chunk de 3s de audio (normal para Whisper)
|
|
55935
|
+
- El session_id debe conservarse durante toda la reuni\xF3n
|
|
55191
55936
|
`
|
|
55192
55937
|
},
|
|
55193
55938
|
{
|
|
@@ -55301,532 +56046,6 @@ Para ejecutar comandos y guardar el output en archivos para logging o procesamie
|
|
|
55301
56046
|
- \u274C Filenames gen\xE9ricos sin timestamp
|
|
55302
56047
|
- \u274C No capturar stderr
|
|
55303
56048
|
`
|
|
55304
|
-
},
|
|
55305
|
-
{
|
|
55306
|
-
name: "voice_output",
|
|
55307
|
-
description: `Convert text to synthesized speech using TTS (Text-to-Speech) providers like ElevenLabs, OpenAI TTS, or Gemini TTS`,
|
|
55308
|
-
category: "voice",
|
|
55309
|
-
version: "1.0.0",
|
|
55310
|
-
tools: ["voice_speak"],
|
|
55311
|
-
triggers: ["le\xE9 esto en voz alta", "read this aloud", "convert\xED a voz", "convert to speech", "habl\xE1 este texto", "speak this text", "texto a voz", "text to speech", "gener\xE1 audio", "generate audio", "s\xEDntesis de voz", "voice synthesis", "escuch\xE1 la respuesta", "listen to response"],
|
|
55312
|
-
body: `
|
|
55313
|
-
# Voice Output Skill
|
|
55314
|
-
|
|
55315
|
-
## Cu\xE1ndo se Activa
|
|
55316
|
-
|
|
55317
|
-
Esta skill se activa cuando el usuario necesita convertir texto a voz: leer respuestas, generar audio, s\xEDntesis de voz.
|
|
55318
|
-
|
|
55319
|
-
## Herramientas Disponibles
|
|
55320
|
-
|
|
55321
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55322
|
-
|------|----------|---------------|
|
|
55323
|
-
| \`voice_speak\` | Convierte texto \u2192 audio | S\xEDntesis de voz |
|
|
55324
|
-
|
|
55325
|
-
## Workflow
|
|
55326
|
-
|
|
55327
|
-
### Text-to-Speech
|
|
55328
|
-
\`\`\`javascript
|
|
55329
|
-
// 1. Recibir texto
|
|
55330
|
-
const text = "Hola, \xBFc\xF3mo est\xE1s?"
|
|
55331
|
-
|
|
55332
|
-
// 2. Preprocesar
|
|
55333
|
-
// - Expandir n\xFAmeros: "5" \u2192 "cinco"
|
|
55334
|
-
// - Expandir fechas: "01/01" \u2192 "primero de enero"
|
|
55335
|
-
// - Expandir abbreviaturas: "Dr." \u2192 "Doctor"
|
|
55336
|
-
|
|
55337
|
-
// 3. Sintetizar
|
|
55338
|
-
const audio = voice_speak({
|
|
55339
|
-
text: optimizedText,
|
|
55340
|
-
voice_id: "eleven_flash_v2_5", // o configured voice
|
|
55341
|
-
language: "es"
|
|
55342
|
-
})
|
|
55343
|
-
|
|
55344
|
-
// 4. Entregar audio
|
|
55345
|
-
// - Enviar como archivo
|
|
55346
|
-
// - Streaming si el canal lo soporta
|
|
55347
|
-
\`\`\`
|
|
55348
|
-
|
|
55349
|
-
## Proveedores TTS Soportados
|
|
55350
|
-
|
|
55351
|
-
| Provider | Modelos | Voces |
|
|
55352
|
-
|----------|---------|-------|
|
|
55353
|
-
| ElevenLabs | Flash V2.5, Turbo V2.5, Multilingual V2, V3 | 1000+ |
|
|
55354
|
-
| OpenAI | tts-1, tts-1-hd, gpt-4o-mini-tts | 6+ |
|
|
55355
|
-
| Gemini | 2.5 Flash TTS, 2.5 Pro TTS | Multi |
|
|
55356
|
-
| Qwen | Qwen TTS Flash, Instruct | Multi |
|
|
55357
|
-
|
|
55358
|
-
## Configuraci\xF3n por Canal
|
|
55359
|
-
|
|
55360
|
-
Cada canal configura su proveedor TTS:
|
|
55361
|
-
- \`tts_provider\`: "elevenlabs" | "openai-tts" | "gemini-tts"
|
|
55362
|
-
- \`tts_voice_id\`: ID espec\xEDfico de voz (ej. ElevenLabs voice ID)
|
|
55363
|
-
|
|
55364
|
-
## Mejores Pr\xE1cticas
|
|
55365
|
-
|
|
55366
|
-
- Preprocesar texto para naturalidad
|
|
55367
|
-
- Usar voz configurada por usuario
|
|
55368
|
-
- Cachear respuestas frecuentes
|
|
55369
|
-
- Split de textos largos
|
|
55370
|
-
|
|
55371
|
-
## Errores a Evitar
|
|
55372
|
-
|
|
55373
|
-
- \u274C Enviar texto crudo sin preprocesar
|
|
55374
|
-
- \u274C Ignorar preferencia de voz
|
|
55375
|
-
- \u274C No manejar l\xEDmites de longitud
|
|
55376
|
-
- \u274C No cachear (costo API)
|
|
55377
|
-
`
|
|
55378
|
-
},
|
|
55379
|
-
{
|
|
55380
|
-
name: "voice_assistant",
|
|
55381
|
-
description: `Full voice-to-voice interaction: transcribe user speech, process request, and respond with synthesized speech`,
|
|
55382
|
-
category: "voice",
|
|
55383
|
-
version: "1.0.0",
|
|
55384
|
-
tools: ["voice_transcribe", "voice_speak"],
|
|
55385
|
-
triggers: ["modo voz", "voice mode", "asistente de voz", "voice assistant", "habl\xE1 conmigo", "talk to me", "interacci\xF3n por voz", "voice interaction", "respuesta hablada", "spoken response", "comando de voz", "voice command", "di\xE1logo por voz", "voice dialogue"],
|
|
55386
|
-
body: `
|
|
55387
|
-
# Voice Assistant Skill
|
|
55388
|
-
|
|
55389
|
-
## Cu\xE1ndo se Activa
|
|
55390
|
-
|
|
55391
|
-
Esta skill se activa para interacci\xF3n completa voz a voz: el usuario habla, el asistente procesa y responde con voz.
|
|
55392
|
-
|
|
55393
|
-
## Herramientas Disponibles
|
|
55394
|
-
|
|
55395
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55396
|
-
|------|----------|---------------|
|
|
55397
|
-
| \`voice_transcribe\` | Audio \u2192 texto | Input del usuario |
|
|
55398
|
-
| \`voice_speak\` | Texto \u2192 audio | Respuesta del asistente |
|
|
55399
|
-
|
|
55400
|
-
## Workflow
|
|
55401
|
-
|
|
55402
|
-
### Voice-to-Voice
|
|
55403
|
-
\`\`\`javascript
|
|
55404
|
-
// 1. Usuario habla
|
|
55405
|
-
const userAudio = receiveAudio()
|
|
55406
|
-
|
|
55407
|
-
// 2. Transcribir
|
|
55408
|
-
const userText = voice_transcribe({
|
|
55409
|
-
audio: userAudio,
|
|
55410
|
-
language: "auto"
|
|
55411
|
-
})
|
|
55412
|
-
// \u2192 "\xBFCu\xE1l es el clima hoy?"
|
|
55413
|
-
|
|
55414
|
-
// 3. Procesar request
|
|
55415
|
-
// - Entender intenci\xF3n
|
|
55416
|
-
// - Ejecutar acci\xF3n (ej. consultar API clima)
|
|
55417
|
-
// - Generar respuesta
|
|
55418
|
-
const responseText = "Hoy hay 25 grados y soleado en Buenos Aires"
|
|
55419
|
-
|
|
55420
|
-
// 4. Sintetizar respuesta
|
|
55421
|
-
const responseAudio = voice_speak({
|
|
55422
|
-
text: responseText,
|
|
55423
|
-
voice_id: "eleven_flash_v2_5",
|
|
55424
|
-
language: "es"
|
|
55425
|
-
})
|
|
55426
|
-
|
|
55427
|
-
// 5. Enviar audio
|
|
55428
|
-
sendAudio(responseAudio)
|
|
55429
|
-
\`\`\`
|
|
55430
|
-
|
|
55431
|
-
## Casos de Uso
|
|
55432
|
-
|
|
55433
|
-
| Caso | Flujo |
|
|
55434
|
-
|------|-------|
|
|
55435
|
-
| Pregunta simple | Transcribe \u2192 responde \u2192 sintetiza |
|
|
55436
|
-
| Comando | Transcribe \u2192 ejecuta \u2192 confirma por voz |
|
|
55437
|
-
| Di\xE1logo | Mantener contexto entre exchanges |
|
|
55438
|
-
| Wake word | Escuchar "hey bee" \u2192 activar \u2192 procesar |
|
|
55439
|
-
|
|
55440
|
-
## Configuraci\xF3n
|
|
55441
|
-
|
|
55442
|
-
### Wake Word
|
|
55443
|
-
\`\`\`json
|
|
55444
|
-
{
|
|
55445
|
-
"voice_wake_word": "hey bee",
|
|
55446
|
-
"voice_wake_enabled": true
|
|
55447
|
-
}
|
|
55448
|
-
\`\`\`
|
|
55449
|
-
|
|
55450
|
-
### Canal Voice
|
|
55451
|
-
\`\`\`json
|
|
55452
|
-
{
|
|
55453
|
-
"voice_enabled": true,
|
|
55454
|
-
"tts_enabled": true,
|
|
55455
|
-
"stt_provider": "groq-whisper",
|
|
55456
|
-
"tts_provider": "elevenlabs",
|
|
55457
|
-
"tts_voice_id": "eleven_flash_v2_5"
|
|
55458
|
-
}
|
|
55459
|
-
\`\`\`
|
|
55460
|
-
|
|
55461
|
-
## Mejores Pr\xE1cticas
|
|
55462
|
-
|
|
55463
|
-
- Respuestas cortas y naturales (<60s)
|
|
55464
|
-
- Mantener contexto conversacional
|
|
55465
|
-
- Indicadores de procesamiento
|
|
55466
|
-
- Fallback a texto si falla voz
|
|
55467
|
-
|
|
55468
|
-
## Errores a Evitar
|
|
55469
|
-
|
|
55470
|
-
- \u274C Respuestas muy largas para audio
|
|
55471
|
-
- \u274C Perder contexto entre exchanges
|
|
55472
|
-
- \u274C No indicar que est\xE1 procesando
|
|
55473
|
-
- \u274C No tener fallback si falla TTS/STT
|
|
55474
|
-
`
|
|
55475
|
-
},
|
|
55476
|
-
{
|
|
55477
|
-
name: "voice_input",
|
|
55478
|
-
description: `Transcribe audio input to text using STT (Speech-to-Text) providers like Groq Whisper or OpenAI Whisper`,
|
|
55479
|
-
category: "voice",
|
|
55480
|
-
version: "1.0.0",
|
|
55481
|
-
tools: ["voice_transcribe"],
|
|
55482
|
-
triggers: ["transcrib\xED este audio", "transcribe audio", "convert\xED voz a texto", "convert voice to text", "qu\xE9 dice el audio", "what does audio say", "escuch\xE1 esto", "listen to this", "audio a texto", "audio to text", "reconocimiento de voz", "speech recognition", "nota de voz", "voice note"],
|
|
55483
|
-
body: `
|
|
55484
|
-
# Voice Input Skill
|
|
55485
|
-
|
|
55486
|
-
## Cu\xE1ndo se Activa
|
|
55487
|
-
|
|
55488
|
-
Esta skill se activa cuando el usuario env\xEDa audio y necesita transcripci\xF3n a texto: notas de voz, grabaciones, comandos de voz.
|
|
55489
|
-
|
|
55490
|
-
## Herramientas Disponibles
|
|
55491
|
-
|
|
55492
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55493
|
-
|------|----------|---------------|
|
|
55494
|
-
| \`voice_transcribe\` | Convierte audio \u2192 texto | Transcripci\xF3n de cualquier audio |
|
|
55495
|
-
|
|
55496
|
-
## Workflow
|
|
55497
|
-
|
|
55498
|
-
### Transcripci\xF3n
|
|
55499
|
-
\`\`\`javascript
|
|
55500
|
-
// 1. Recibir audio
|
|
55501
|
-
// - File upload
|
|
55502
|
-
// - Voice message (Telegram, WhatsApp)
|
|
55503
|
-
// - Stream en vivo
|
|
55504
|
-
|
|
55505
|
-
// 2. Transcribir
|
|
55506
|
-
const result = voice_transcribe({
|
|
55507
|
-
audio: audioBuffer,
|
|
55508
|
-
language: "es" // o "auto" para detectar
|
|
55509
|
-
})
|
|
55510
|
-
|
|
55511
|
-
// 3. Formatear
|
|
55512
|
-
// - Agregar puntuaci\xF3n
|
|
55513
|
-
// - Capitalizar
|
|
55514
|
-
// - Marcar speakers si hay m\xFAltiples
|
|
55515
|
-
|
|
55516
|
-
// 4. Entregar resultado
|
|
55517
|
-
\`\`\`
|
|
55518
|
-
|
|
55519
|
-
## Proveedores STT Soportados
|
|
55520
|
-
|
|
55521
|
-
| Provider | Modelos | Idiomas |
|
|
55522
|
-
|----------|---------|---------|
|
|
55523
|
-
| Groq | whisper-large-v3, turbo | Multi |
|
|
55524
|
-
| OpenAI | whisper-1 | Multi |
|
|
55525
|
-
|
|
55526
|
-
## Configuraci\xF3n por Canal
|
|
55527
|
-
|
|
55528
|
-
Cada canal puede configurar su proveedor STT preferido:
|
|
55529
|
-
- \`stt_provider\`: "groq-whisper" | "openai-whisper"
|
|
55530
|
-
|
|
55531
|
-
## Mejores Pr\xE1cticas
|
|
55532
|
-
|
|
55533
|
-
- Detectar idioma autom\xE1ticamente
|
|
55534
|
-
- Agregar puntuaci\xF3n para legibilidad
|
|
55535
|
-
- Marcar segmentos inaudibles
|
|
55536
|
-
- Preservar idioma original
|
|
55537
|
-
|
|
55538
|
-
## Errores a Evitar
|
|
55539
|
-
|
|
55540
|
-
- \u274C Traducir sin pedir (mantener idioma)
|
|
55541
|
-
- \u274C Omitir puntuaci\xF3n
|
|
55542
|
-
- \u274C No indicar baja confianza
|
|
55543
|
-
- \u274C Ignorar ruido de fondo que afecta calidad
|
|
55544
|
-
`
|
|
55545
|
-
},
|
|
55546
|
-
{
|
|
55547
|
-
name: "cron_manager",
|
|
55548
|
-
description: `Complete management of cron jobs with cron expressions. Create, list, update, pause, resume, delete, trigger, and view history. Use for reminders, automated reports, periodic checks.`,
|
|
55549
|
-
category: "cron",
|
|
55550
|
-
version: "2.0.0",
|
|
55551
|
-
tools: ["cron.create", "cron.list", "cron.update", "cron.delete", "cron.pause", "cron.resume", "cron.trigger", "cron.history"],
|
|
55552
|
-
triggers: ["program\xE1 una tarea", "schedule task", "cre\xE1 un cron", "create cron", "edit\xE1 el cron", "edit cron", "elimin\xE1 el cron", "remove cron", "lista las tareas", "list cron jobs", "modific\xE1 el cron", "modify cron", "tarea recurrente", "recurring task", "todos los d\xEDas", "daily", "cada semana", "weekly"],
|
|
55553
|
-
body: `
|
|
55554
|
-
# Cron Manager Skill
|
|
55555
|
-
|
|
55556
|
-
## Cu\xE1ndo se Activa
|
|
55557
|
-
|
|
55558
|
-
Para gestionar tareas programadas (cron jobs): crear, listar, actualizar, pausar, reanudar, eliminar, ejecutar y ver historial.
|
|
55559
|
-
|
|
55560
|
-
## Herramientas Disponibles
|
|
55561
|
-
|
|
55562
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55563
|
-
|------|----------|---------------|
|
|
55564
|
-
| \`cron.create\` | Crear cron job | Nueva tarea |
|
|
55565
|
-
| \`cron.list\` | Listar todos | Ver existentes |
|
|
55566
|
-
| \`cron.update\` | Actualizar existente | Cambiar horario/instrucci\xF3n |
|
|
55567
|
-
| \`cron.pause\` | Pausar temporalmente | Sin eliminar |
|
|
55568
|
-
| \`cron.resume\` | Reanudar pausado | Continuar ejecuci\xF3n |
|
|
55569
|
-
| \`cron.delete\` | Eliminar permanentemente | Cancelar para siempre |
|
|
55570
|
-
| \`cron.trigger\` | Ejecutar ahora | Forzar ejecuci\xF3n |
|
|
55571
|
-
| \`cron.history\` | Ver historial | Ver logs de ejecuciones |
|
|
55572
|
-
|
|
55573
|
-
## Campos Principales
|
|
55574
|
-
|
|
55575
|
-
| Campo | Tipo | Descripci\xF3n |
|
|
55576
|
-
|-------|------|-------------|
|
|
55577
|
-
| \`name\` | string | Identificador corto (e.g., 'daily-report') |
|
|
55578
|
-
| \`task\` | string | **REQUERIDO** - Instrucciones para el agente al ejecutarse |
|
|
55579
|
-
| \`task_type\` | string | 'recurring' (repite) o 'one_shot' (una vez) |
|
|
55580
|
-
| \`cron_expression\` | string | Expresi\xF3n cron (solo para recurring) |
|
|
55581
|
-
| \`fire_at\` | string | Datetime ISO (solo para one_shot) |
|
|
55582
|
-
| \`channel\` | string | Canal de notificaci\xF3n |
|
|
55583
|
-
| \`start_at\` | string | Inicio de ventana opcional (Croner startAt) |
|
|
55584
|
-
| \`stop_at\` | string | Fin de ventana opcional (Croner stopAt) |
|
|
55585
|
-
| \`dom_and_dow\` | number | 0=OR (default), 1=AND (d\xEDa mes + d\xEDa semana) |
|
|
55586
|
-
|
|
55587
|
-
## Cron Expression Format
|
|
55588
|
-
|
|
55589
|
-
\`\`\`
|
|
55590
|
-
* * * * *
|
|
55591
|
-
\u2502 \u2502 \u2502 \u2502 \u2502
|
|
55592
|
-
\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 D\xEDa semana (0-6, 0=Domingo)
|
|
55593
|
-
\u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500 Mes (1-12)
|
|
55594
|
-
\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500 D\xEDa del mes (1-31)
|
|
55595
|
-
\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Hora (0-23)
|
|
55596
|
-
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Minuto (0-59)
|
|
55597
|
-
\`\`\`
|
|
55598
|
-
|
|
55599
|
-
## Ejemplos Comunes
|
|
55600
|
-
|
|
55601
|
-
| Expresi\xF3n | Significado |
|
|
55602
|
-
|-----------|-------------|
|
|
55603
|
-
| \`0 9 * * *\` | Diario 9:00 AM |
|
|
55604
|
-
| \`0 7 * * 1-5\` | Lun-Vie 7:00 AM |
|
|
55605
|
-
| \`0 */2 * * *\` | Cada 2 horas |
|
|
55606
|
-
| \`0 0 * * 0\` | Domingos medianoche |
|
|
55607
|
-
| \`0 0 1 * *\` | D\xEDa 1 de cada mes |
|
|
55608
|
-
|
|
55609
|
-
## C\xF3mo Usar start_at / stop_at
|
|
55610
|
-
|
|
55611
|
-
- \`start_at\`: La tarea no ejecuta antes de esta fecha
|
|
55612
|
-
- \`stop_at\`: La tarea no ejecuta despu\xE9s de esta fecha
|
|
55613
|
-
- Formato ISO: \`'2026-04-01T00:00:00'\`
|
|
55614
|
-
|
|
55615
|
-
## C\xF3mo Usar dom_and_dow
|
|
55616
|
-
|
|
55617
|
-
- \`0\` (default): Se ejecuta si es el d\xEDa del mes O el d\xEDa de semana
|
|
55618
|
-
- \`1\`: Se ejecuta solo si es EL MISMO d\xEDa del mes Y el d\xEDa de semana
|
|
55619
|
-
|
|
55620
|
-
Ejemplo: \`0 9 15 * *\` con dom_and_dow=1 significa "los 15 de cada mes QUE SEA domingo"
|
|
55621
|
-
|
|
55622
|
-
## Workflow para Crear
|
|
55623
|
-
|
|
55624
|
-
1. **Preguntar** \u2192 \xBFone_shot o recurring?
|
|
55625
|
-
2. **Obtener** \u2192 Hora y canal de notificaci\xF3n
|
|
55626
|
-
3. **Crear** \u2192 \`cron.create\` con campo \`task\` obligatorio
|
|
55627
|
-
4. **Confirmar** \u2192 \`cron.list\` mostrar next runs
|
|
55628
|
-
|
|
55629
|
-
## Errores a Evitar
|
|
55630
|
-
|
|
55631
|
-
- \u274C Olvidar el campo \`task\` \u2014 es obligatorio
|
|
55632
|
-
- \u274C Usar exec para tareas programadas
|
|
55633
|
-
- \u274C No preguntar si es one_shot o recurring
|
|
55634
|
-
- \u274C No mostrar pr\xF3ximos horarios al crear
|
|
55635
|
-
- \u274C Llamar \`cron.update\` sin \`task_id\` \u2014 siempre hacer \`cron.list\` primero`
|
|
55636
|
-
},
|
|
55637
|
-
{
|
|
55638
|
-
name: "file_writer",
|
|
55639
|
-
description: `Create, modify, and delete files with safe edit operations and confirmation for large changes`,
|
|
55640
|
-
category: "filesystem",
|
|
55641
|
-
version: "1.0.0",
|
|
55642
|
-
tools: ["project_read", "project_write", "project_edit", "project_exists"],
|
|
55643
|
-
triggers: ["cre\xE1 un archivo", "create a file", "escrib\xED en", "write to", "edit\xE1 este archivo", "edit this file", "modific\xE1", "modify", "elimin\xE1 el archivo", "delete file", "guard\xE1 esto", "save this", "actualiz\xE1 el archivo", "update file"],
|
|
55644
|
-
body: `
|
|
55645
|
-
# File Writer Skill
|
|
55646
|
-
|
|
55647
|
-
## Cu\xE1ndo se Activa
|
|
55648
|
-
|
|
55649
|
-
Esta skill se activa cuando el usuario necesita:
|
|
55650
|
-
- Crear nuevos archivos
|
|
55651
|
-
- Modificar contenido existente
|
|
55652
|
-
- Eliminar archivos
|
|
55653
|
-
- Guardar cambios
|
|
55654
|
-
|
|
55655
|
-
## Herramientas Disponibles
|
|
55656
|
-
|
|
55657
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55658
|
-
|------|----------|---------------|
|
|
55659
|
-
| \`project_read\` | Lee archivo existente | Antes de editar para entender estructura |
|
|
55660
|
-
| \`project_write\` | Crea o sobreescribe archivo | Archivos nuevos o reescritura completa |
|
|
55661
|
-
| \`project_edit\` | Edita secciones espec\xEDficas | Cambios puntuales (find/replace) |
|
|
55662
|
-
| \`project_exists\` | Verifica existencia | Para decidir crear vs editar |
|
|
55663
|
-
|
|
55664
|
-
## Workflow
|
|
55665
|
-
|
|
55666
|
-
### Crear Archivo Nuevo
|
|
55667
|
-
1. \`project_exists({ path })\` \u2192 verificar no existe
|
|
55668
|
-
2. \`project_write({ path, content })\` \u2192 crear
|
|
55669
|
-
|
|
55670
|
-
### Editar Archivo Existente
|
|
55671
|
-
1. \`project_exists({ path })\` \u2192 verificar existe
|
|
55672
|
-
2. \`project_read({ path })\` \u2192 entender estructura
|
|
55673
|
-
3. \`project_edit({ path, old_string, new_string })\` \u2192 modificar
|
|
55674
|
-
4. \`canvas_confirm()\` si cambios >50 l\xEDneas
|
|
55675
|
-
|
|
55676
|
-
### Eliminar Archivo
|
|
55677
|
-
1. \`project_exists({ path })\` \u2192 verificar existe
|
|
55678
|
-
2. \`canvas_confirm({ message: '\xBFEliminar archivo?' })\` \u2192 confirmar
|
|
55679
|
-
3. Operaci\xF3n de delete
|
|
55680
|
-
|
|
55681
|
-
## Mejores Pr\xE1cticas
|
|
55682
|
-
|
|
55683
|
-
- **Leer antes de editar**: Nunca modificar sin entender estructura
|
|
55684
|
-
- **Edit vs Write**: Usar edit para cambios peque\xF1os, write para nuevos archivos
|
|
55685
|
-
- **Confirmar cambios grandes**: >50 l\xEDneas requiere confirmaci\xF3n expl\xEDcita
|
|
55686
|
-
- **Paths seguros**: Trabajar dentro del workspace por defecto
|
|
55687
|
-
|
|
55688
|
-
## Errores a Evitar
|
|
55689
|
-
|
|
55690
|
-
- \u274C Editar sin leer primero
|
|
55691
|
-
- \u274C Sobreescribir sin confirmar si es cambio grande
|
|
55692
|
-
- \u274C Eliminar sin confirmaci\xF3n expl\xEDcita
|
|
55693
|
-
- \u274C Usar write cuando edit es suficiente
|
|
55694
|
-
`
|
|
55695
|
-
},
|
|
55696
|
-
{
|
|
55697
|
-
name: "file_read_and_summarize",
|
|
55698
|
-
description: `Read and understand file content with automatic summarization for large files`,
|
|
55699
|
-
category: "filesystem",
|
|
55700
|
-
version: "1.0.0",
|
|
55701
|
-
tools: ["project_read"],
|
|
55702
|
-
triggers: ["le\xE9 este archivo", "read this file", "mostrame el contenido", "show content", "qu\xE9 dice este archivo", "resum\xED este archivo", "summarize this file", "entend\xE9 este c\xF3digo", "understand this code"],
|
|
55703
|
-
body: `
|
|
55704
|
-
# File Read and Summarize Skill
|
|
55705
|
-
|
|
55706
|
-
## Cu\xE1ndo se Activa
|
|
55707
|
-
|
|
55708
|
-
Esta skill se activa cuando el usuario necesita leer y entender el contenido de un archivo, especialmente cuando:
|
|
55709
|
-
- El archivo es grande y necesita resumen
|
|
55710
|
-
- Se requiere comprensi\xF3n del contenido (no solo lectura)
|
|
55711
|
-
- El usuario pide "qu\xE9 dice", "resum\xED", "entend\xE9"
|
|
55712
|
-
|
|
55713
|
-
## Herramientas Disponibles
|
|
55714
|
-
|
|
55715
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55716
|
-
|------|----------|---------------|
|
|
55717
|
-
| \`project_read\` | Lee contenido de archivo del workspace | Lectura de cualquier archivo |
|
|
55718
|
-
|
|
55719
|
-
## Workflow
|
|
55720
|
-
|
|
55721
|
-
1. **Verificar existencia** \u2192 \`project_exists({ path })\`
|
|
55722
|
-
2. **Leer contenido** \u2192 \`project_read({ path, offset, limit })\`
|
|
55723
|
-
3. **Sintetizar** \u2192 Resumir si es grande, extraer puntos clave
|
|
55724
|
-
|
|
55725
|
-
## Mejores Pr\xE1cticas
|
|
55726
|
-
|
|
55727
|
-
- Para archivos >1000 l\xEDneas, usar \`offset\` y \`limit\`
|
|
55728
|
-
- Identificar tipo de archivo por extensi\xF3n y adaptar formato de resumen
|
|
55729
|
-
- Para c\xF3digo: identificar funciones, clases, exports principales
|
|
55730
|
-
- Para config: explicar settings clave en lenguaje simple
|
|
55731
|
-
- Para texto: extraer ideas principales
|
|
55732
|
-
|
|
55733
|
-
## Errores a Evitar
|
|
55734
|
-
|
|
55735
|
-
- \u274C Leer sin verificar existencia
|
|
55736
|
-
- \u274C Retornar archivo completo sin resumir si es muy grande
|
|
55737
|
-
- \u274C No identificar tipo de archivo para adaptar resumen
|
|
55738
|
-
`
|
|
55739
|
-
},
|
|
55740
|
-
{
|
|
55741
|
-
name: "file_manager",
|
|
55742
|
-
description: `Explore project structure and locate files using glob patterns and directory listing`,
|
|
55743
|
-
category: "filesystem",
|
|
55744
|
-
version: "1.0.0",
|
|
55745
|
-
tools: ["fs_list", "fs_glob", "fs_exists"],
|
|
55746
|
-
triggers: ["lista los archivos", "list files", "busc\xE1 archivos", "find files", "explor\xE1 el proyecto", "explore project", "qu\xE9 archivos hay", "what files exist", "busc\xE1 por patr\xF3n", "search by pattern", "existe este archivo", "file exists", "d\xF3nde est\xE1", "where is"],
|
|
55747
|
-
body: `
|
|
55748
|
-
# File Manager Skill
|
|
55749
|
-
|
|
55750
|
-
## Cu\xE1ndo se Activa
|
|
55751
|
-
|
|
55752
|
-
Esta skill se activa cuando el usuario necesita:
|
|
55753
|
-
- Explorar la estructura del proyecto
|
|
55754
|
-
- Buscar archivos por extensi\xF3n o patr\xF3n
|
|
55755
|
-
- Verificar si existe un archivo o directorio
|
|
55756
|
-
- Encontrar la ubicaci\xF3n de un archivo
|
|
55757
|
-
|
|
55758
|
-
## Herramientas Disponibles
|
|
55759
|
-
|
|
55760
|
-
| Tool | Qu\xE9 hace | Cu\xE1ndo usarla |
|
|
55761
|
-
|------|----------|---------------|
|
|
55762
|
-
| \`fs_list\` | Lista directorios y archivos | Exploraci\xF3n inicial |
|
|
55763
|
-
| \`fs_glob\` | Busca archivos por patr\xF3n wildcard | B\xFAsqueda por extensi\xF3n/patr\xF3n |
|
|
55764
|
-
| \`fs_exists\` | Verifica existencia | Pre-check antes de operaciones |
|
|
55765
|
-
|
|
55766
|
-
## Workflow
|
|
55767
|
-
|
|
55768
|
-
1. **Explorar** \u2192 \`fs_list({ path })\` para estructura general
|
|
55769
|
-
2. **Buscar por patr\xF3n** \u2192 \`fs_glob({ pattern })\` para tipos espec\xEDficos
|
|
55770
|
-
3. **Verificar** \u2192 \`fs_exists({ path })\` para confirmaci\xF3n
|
|
55771
|
-
|
|
55772
|
-
## Patrones Glob Comunes
|
|
55773
|
-
|
|
55774
|
-
| Patr\xF3n | Encuentra |
|
|
55775
|
-
|--------|-----------|
|
|
55776
|
-
| \`**/*.ts\` | Todos los TypeScript |
|
|
55777
|
-
| \`**/*.test.ts\` | Solo tests |
|
|
55778
|
-
| \`**/*.md\` | Documentaci\xF3n |
|
|
55779
|
-
| \`**/package.json\` | Todos los package.json |
|
|
55780
|
-
| \`src/**/*.tsx\` | React components en src |
|
|
55781
|
-
|
|
55782
|
-
## Errores a Evitar
|
|
55783
|
-
|
|
55784
|
-
- \u274C No verificar existencia antes de leer/editar
|
|
55785
|
-
- \u274C Usar fs_list cuando se conoce el patr\xF3n (usar glob)
|
|
55786
|
-
- \u274C Patrones muy amplios sin filtrado
|
|
55787
|
-
`
|
|
55788
|
-
},
|
|
55789
|
-
{
|
|
55790
|
-
name: "cron_reminder",
|
|
55791
|
-
description: `Schedule a reminder for yourself at a specific time. Creates a one_shot cron job that sends a notification message via your preferred channel.`,
|
|
55792
|
-
category: "cron",
|
|
55793
|
-
version: "2.0.0",
|
|
55794
|
-
tools: ["cron.create", "notify"],
|
|
55795
|
-
triggers: ["recordame", "remind me", "recordatorio", "reminder", "alerta", "alert", "av\xEDsame", "notify me", "program\xE1", "schedule", "para ma\xF1ana", "for tomorrow", "en 30 minutos", "in 30 minutes"],
|
|
55796
|
-
body: `
|
|
55797
|
-
# Cron Reminder Skill
|
|
55798
|
-
|
|
55799
|
-
## Cu\xE1ndo se Activa
|
|
55800
|
-
|
|
55801
|
-
Para crear recordatorios de una sola ejecuci\xF3n (one_shot): "recuerdame a las 3pm", "av\xEDsame en 30 minutos", etc.
|
|
55802
|
-
|
|
55803
|
-
## Herramientas
|
|
55804
|
-
|
|
55805
|
-
| Tool | Qu\xE9 hace |
|
|
55806
|
-
|------|----------|
|
|
55807
|
-
| \`cron.create\` | Crear recordatorio one_shot |
|
|
55808
|
-
| \`notify\` | Enviar notificaci\xF3n directa |
|
|
55809
|
-
|
|
55810
|
-
## C\xF3mo Funciona
|
|
55811
|
-
|
|
55812
|
-
1. **Preguntar** \u2192 \xBFDe qu\xE9 te aviso? \xBFA qu\xE9 hora? \xBFPor qu\xE9 canal?
|
|
55813
|
-
2. **Crear** \u2192 \`cron.create\` con \`task_type: 'one_shot'\` y \`fire_at\` en formato ISO
|
|
55814
|
-
3. **Confirmar** \u2192 Mostrar hora programada
|
|
55815
|
-
|
|
55816
|
-
## Par\xE1metros
|
|
55817
|
-
|
|
55818
|
-
| Campo | Descripci\xF3n |
|
|
55819
|
-
|-------|-------------|
|
|
55820
|
-
| \`task\` | **REQUERIDO** - Mensaje del recordatorio |
|
|
55821
|
-
| \`task_type\` | Siempre \`'one_shot'\` |
|
|
55822
|
-
| \`fire_at\` | Fecha/hora ISO (ej: \`'2026-04-20T15:00:00'\`) |
|
|
55823
|
-
| \`channel\` | Canal (telegram, discord, whatsapp, webchat) |
|
|
55824
|
-
|
|
55825
|
-
## Errores Comunes
|
|
55826
|
-
|
|
55827
|
-
- \u274C Olvidar el campo \`task\` \u2014 obligatorio para que el agente sepa qu\xE9 enviar
|
|
55828
|
-
- \u274C Usar expresiones cron para recordatorios (usar \`fire_at\` en vez de \`cron_expression\`)
|
|
55829
|
-
- \u274C Poner \`fire_at\` en el pasado`
|
|
55830
56049
|
}
|
|
55831
56050
|
];
|
|
55832
56051
|
});
|
|
@@ -56069,7 +56288,7 @@ var init_src = __esm(() => {
|
|
|
56069
56288
|
});
|
|
56070
56289
|
|
|
56071
56290
|
// packages/core/src/storage/seed.ts
|
|
56072
|
-
var SEED_DATA,
|
|
56291
|
+
var SEED_DATA, log43, INITIAL_PLAYBOOK_RULES;
|
|
56073
56292
|
var init_seed = __esm(() => {
|
|
56074
56293
|
init_sqlite();
|
|
56075
56294
|
init_logger();
|
|
@@ -56157,7 +56376,8 @@ var init_seed = __esm(() => {
|
|
|
56157
56376
|
{ id: "nvidia", name: "NVIDIA NIM", baseUrl: "https://integrate.api.nvidia.com/v1" },
|
|
56158
56377
|
{ id: "minimax", name: "MiniMax", baseUrl: "https://api.minimaxi.com/v1" },
|
|
56159
56378
|
{ id: "opencode-go", name: "OpenCode Go", baseUrl: "https://opencode.ai/zen/go/v1" },
|
|
56160
|
-
{ id: "piper", name: "Piper (Local TTS)" }
|
|
56379
|
+
{ id: "piper", name: "Piper (Local TTS)" },
|
|
56380
|
+
{ id: "hiveagents", name: "HiveAgents LLM (Cloudflare)", baseUrl: "https://llm.hiveagents.io/v1", category: "llm" }
|
|
56161
56381
|
],
|
|
56162
56382
|
models: [
|
|
56163
56383
|
{ id: "claude-opus-4-6", providerId: "anthropic", name: "Claude Opus 4.6", modelType: "llm", contextWindow: 200000, capabilities: JSON.stringify(["chat", "vision", "json_mode", "function_calling", "streaming", "code", "reasoning"]) },
|
|
@@ -56282,7 +56502,16 @@ var init_seed = __esm(() => {
|
|
|
56282
56502
|
{ id: "opencode-go/mimo-v2-omni", providerId: "opencode-go", name: "MiMo-V2 Omni", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
|
|
56283
56503
|
{ id: "opencode-go/mimo-v2.5-pro", providerId: "opencode-go", name: "MiMo-V2.5 Pro", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming", "reasoning"]) },
|
|
56284
56504
|
{ id: "opencode-go/mimo-v2.5", providerId: "opencode-go", name: "MiMo-V2.5", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
|
|
56285
|
-
{ id: "opencode-go/hy3-preview", providerId: "opencode-go", name: "Hunyuan 3 Preview", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) }
|
|
56505
|
+
{ id: "opencode-go/hy3-preview", providerId: "opencode-go", name: "Hunyuan 3 Preview", modelType: "llm", contextWindow: 128000, capabilities: JSON.stringify(["chat", "code", "function_calling", "streaming"]) },
|
|
56506
|
+
{ id: "Qwen3.6-35B-A3B-UD-Q6_K.gguf", providerId: "hiveagents", name: "Qwen3.6 35B MoE (Recomendado)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
|
|
56507
|
+
{ id: "Qwen3.6-35B-A3B-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Qwen3.6 35B MoE (Q4_K_M)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
|
|
56508
|
+
{ id: "Qwen3.6-27B-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Qwen3.6 27B + MTP", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
|
|
56509
|
+
{ id: "Qwen3-Coder-Next-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Qwen3 Coder Next", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "code"]) },
|
|
56510
|
+
{ id: "Qwopus3.6-27B-v2-MTP-Q6_K.gguf", providerId: "hiveagents", name: "Qwopus3.6 27B v2 (Q6_K)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
|
|
56511
|
+
{ id: "Qwopus3.6-27B-v2-MTP-Q4_K_S.gguf", providerId: "hiveagents", name: "Qwopus3.6 27B v2 (Q4_K_S)", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming", "reasoning"]) },
|
|
56512
|
+
{ id: "gemma-4-31B-it-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Gemma 4 31B Dense", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) },
|
|
56513
|
+
{ id: "gemma-4-26B-A4B-it-UD-Q4_K_M.gguf", providerId: "hiveagents", name: "Gemma 4 26B MoE", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) },
|
|
56514
|
+
{ id: "gemma-4-12b-it-UD-Q4_K_XL.gguf", providerId: "hiveagents", name: "Gemma 4 12B Dense", modelType: "llm", contextWindow: 50000, capabilities: JSON.stringify(["chat", "streaming"]) }
|
|
56286
56515
|
],
|
|
56287
56516
|
mcpServers: [],
|
|
56288
56517
|
channels: [
|
|
@@ -56320,7 +56549,7 @@ Estos lineamientos tienen M\xC1XIMA prioridad sobre cualquier otra instrucci\xF3
|
|
|
56320
56549
|
}
|
|
56321
56550
|
]
|
|
56322
56551
|
};
|
|
56323
|
-
|
|
56552
|
+
log43 = logger.child("seed");
|
|
56324
56553
|
INITIAL_PLAYBOOK_RULES = [
|
|
56325
56554
|
{
|
|
56326
56555
|
rule: "Cuando el usuario pida buscar noticias recientes, usa web_search con filtros de fecha en lugar de http_client gen\xE9rico",
|
|
@@ -56372,7 +56601,7 @@ function getSingleUserId() {
|
|
|
56372
56601
|
const result = db.query("SELECT id FROM users LIMIT 1").get();
|
|
56373
56602
|
return result?.id || null;
|
|
56374
56603
|
} catch (e) {
|
|
56375
|
-
|
|
56604
|
+
log44.warn("[getSingleUserId] \u26A0\uFE0F Error getting user ID:", e.message);
|
|
56376
56605
|
return null;
|
|
56377
56606
|
}
|
|
56378
56607
|
}
|
|
@@ -56382,7 +56611,7 @@ function getUserIdFromChannelIdentity(channel, channelUserId) {
|
|
|
56382
56611
|
const result = db.query("SELECT user_id FROM user_identities WHERE channel = ? AND channel_user_id = ? LIMIT 1").get(channel, channelUserId);
|
|
56383
56612
|
return result?.user_id || null;
|
|
56384
56613
|
} catch (e) {
|
|
56385
|
-
|
|
56614
|
+
log44.warn("[getUserIdFromChannelIdentity] \u26A0\uFE0F Error getting user ID from channel identity:", e.message);
|
|
56386
56615
|
return null;
|
|
56387
56616
|
}
|
|
56388
56617
|
}
|
|
@@ -56412,7 +56641,7 @@ function getDefaultAgentId() {
|
|
|
56412
56641
|
const firstAgent = db.query("SELECT id FROM agents WHERE enabled = 1 LIMIT 1").get();
|
|
56413
56642
|
return firstAgent?.id || null;
|
|
56414
56643
|
} catch (e) {
|
|
56415
|
-
|
|
56644
|
+
log44.warn("[getDefaultAgentId] \u26A0\uFE0F Error getting default agent ID:", e.message);
|
|
56416
56645
|
return null;
|
|
56417
56646
|
}
|
|
56418
56647
|
}
|
|
@@ -56422,14 +56651,14 @@ function resolveAgentId(agentId) {
|
|
|
56422
56651
|
}
|
|
56423
56652
|
return getDefaultAgentId();
|
|
56424
56653
|
}
|
|
56425
|
-
var
|
|
56654
|
+
var log44;
|
|
56426
56655
|
var init_onboarding = __esm(() => {
|
|
56427
56656
|
init_logger();
|
|
56428
56657
|
init_sqlite();
|
|
56429
56658
|
init_crypto();
|
|
56430
56659
|
init_seed();
|
|
56431
56660
|
init_src();
|
|
56432
|
-
|
|
56661
|
+
log44 = logger.child("onboarding");
|
|
56433
56662
|
});
|
|
56434
56663
|
|
|
56435
56664
|
// packages/core/src/agent/prompt-builder.ts
|
|
@@ -56455,7 +56684,7 @@ ${rule.content}`;
|
|
|
56455
56684
|
${ethicsContent}
|
|
56456
56685
|
|
|
56457
56686
|
`;
|
|
56458
|
-
|
|
56687
|
+
log45.info(`[prompt-builder] Loaded ${ethicsRules.length} ethics rules`);
|
|
56459
56688
|
} else {
|
|
56460
56689
|
ethicsSection = `# \xC9TICA Y REGLAS CONSTITUCIONALES
|
|
56461
56690
|
|
|
@@ -56567,20 +56796,20 @@ ${agent.system_prompt}
|
|
|
56567
56796
|
`;
|
|
56568
56797
|
}
|
|
56569
56798
|
const systemPrompt = `${ethicsSection}${agentSection}${userSection}`.trim();
|
|
56570
|
-
|
|
56799
|
+
log45.info(`[prompt-builder] Built system prompt for agent=${agent.name} role=${agent.role}`);
|
|
56571
56800
|
return systemPrompt;
|
|
56572
56801
|
}
|
|
56573
56802
|
async function buildSystemPromptWithProjects(opts) {
|
|
56574
56803
|
const userId = opts.userId || resolveUserId({}) || "default";
|
|
56575
56804
|
return buildSystemPrompt({ agentId: opts.agentId, userId });
|
|
56576
56805
|
}
|
|
56577
|
-
var
|
|
56806
|
+
var log45;
|
|
56578
56807
|
var init_prompt_builder = __esm(() => {
|
|
56579
56808
|
init_sqlite();
|
|
56580
56809
|
init_logger();
|
|
56581
56810
|
init_toon();
|
|
56582
56811
|
init_onboarding();
|
|
56583
|
-
|
|
56812
|
+
log45 = logger.child("prompt-builder");
|
|
56584
56813
|
});
|
|
56585
56814
|
|
|
56586
56815
|
// packages/core/src/mcp/singleton.ts
|
|
@@ -56602,7 +56831,7 @@ function syncMCPToolsToDB(serverId, serverName, tools) {
|
|
|
56602
56831
|
const deleteExisting = db.prepare("DELETE FROM mcp_tools WHERE server_id = ?");
|
|
56603
56832
|
deleteExisting.run(serverId);
|
|
56604
56833
|
if (tools.length === 0) {
|
|
56605
|
-
|
|
56834
|
+
log46.debug(`[mcp:tool-sync] No tools to persist for server ${serverName}`);
|
|
56606
56835
|
return;
|
|
56607
56836
|
}
|
|
56608
56837
|
const insertTool = db.prepare(`
|
|
@@ -56615,9 +56844,9 @@ function syncMCPToolsToDB(serverId, serverName, tools) {
|
|
|
56615
56844
|
insertTool.run(id, serverId, serverName, tool.name, tool.description || "");
|
|
56616
56845
|
count++;
|
|
56617
56846
|
}
|
|
56618
|
-
|
|
56847
|
+
log46.info(`[mcp:tool-sync] Persisted ${count} MCP tools for server ${serverName} to mcp_tools`);
|
|
56619
56848
|
} catch (err) {
|
|
56620
|
-
|
|
56849
|
+
log46.error(`[mcp:tool-sync] Failed to persist MCP tools for server ${serverName}:`, err);
|
|
56621
56850
|
}
|
|
56622
56851
|
}
|
|
56623
56852
|
async function syncMCPToolsToFTS() {
|
|
@@ -56635,7 +56864,7 @@ async function syncMCPToolsToFTS() {
|
|
|
56635
56864
|
WHERE active = 1
|
|
56636
56865
|
`).all();
|
|
56637
56866
|
if (mcpTools.length === 0) {
|
|
56638
|
-
|
|
56867
|
+
log46.debug(`[mcp:tool-sync] No MCP tools to sync to FTS5`);
|
|
56639
56868
|
return;
|
|
56640
56869
|
}
|
|
56641
56870
|
const insert = db.prepare(`
|
|
@@ -56645,18 +56874,18 @@ async function syncMCPToolsToFTS() {
|
|
|
56645
56874
|
for (const tool of mcpTools) {
|
|
56646
56875
|
insert.run(tool.id, tool.server_name, tool.tool_name, tool.description, tool.category);
|
|
56647
56876
|
}
|
|
56648
|
-
|
|
56877
|
+
log46.info(`[mcp:tool-sync] Synced ${mcpTools.length} MCP tools to mcp_tools_fts`);
|
|
56649
56878
|
});
|
|
56650
56879
|
syncTransaction();
|
|
56651
56880
|
} catch (err) {
|
|
56652
|
-
|
|
56881
|
+
log46.error(`[mcp:tool-sync] Failed to sync MCP tools to FTS5:`, err);
|
|
56653
56882
|
}
|
|
56654
56883
|
}
|
|
56655
|
-
var
|
|
56884
|
+
var log46;
|
|
56656
56885
|
var init_tool_sync = __esm(() => {
|
|
56657
56886
|
init_sqlite();
|
|
56658
56887
|
init_logger();
|
|
56659
|
-
|
|
56888
|
+
log46 = logger.child("mcp:tool-sync");
|
|
56660
56889
|
});
|
|
56661
56890
|
|
|
56662
56891
|
// packages/core/src/utils/date.ts
|
|
@@ -56703,7 +56932,7 @@ async function compileContext(opts) {
|
|
|
56703
56932
|
const effectiveMcpManager = mcpManager ?? (() => {
|
|
56704
56933
|
const singletonMcp = getMCPManager();
|
|
56705
56934
|
if (singletonMcp) {
|
|
56706
|
-
|
|
56935
|
+
log47.info(`[context-compiler] Using MCP Manager from singleton`);
|
|
56707
56936
|
return singletonMcp;
|
|
56708
56937
|
}
|
|
56709
56938
|
return null;
|
|
@@ -56713,19 +56942,19 @@ async function compileContext(opts) {
|
|
|
56713
56942
|
channel: opts.channel,
|
|
56714
56943
|
channelUserId: threadId
|
|
56715
56944
|
}) || threadId || "";
|
|
56716
|
-
|
|
56945
|
+
log47.info(`[context-compiler] [STEP-1] Loading agent config for id=${agentId}`);
|
|
56717
56946
|
let agent;
|
|
56718
56947
|
try {
|
|
56719
56948
|
agent = db.query("SELECT * FROM agents WHERE id = ?").get(agentId);
|
|
56720
56949
|
} catch (err) {
|
|
56721
|
-
|
|
56950
|
+
log47.error(`[context-compiler] [STEP-1] \u274C FAILED loading agent: ${JSON.stringify(err)}`);
|
|
56722
56951
|
throw err;
|
|
56723
56952
|
}
|
|
56724
56953
|
if (!agent) {
|
|
56725
56954
|
throw new Error(`Agent not found: ${agentId}`);
|
|
56726
56955
|
}
|
|
56727
56956
|
const isWorker = agent.role === "worker" || !!isolated;
|
|
56728
|
-
|
|
56957
|
+
log47.info(`[context-compiler] [STEP-1] \u2705 Compiling for ${isWorker ? "worker" : "coordinator"} agent=${agent.name}`);
|
|
56729
56958
|
let modelContextWindow = DEFAULT_CONTEXT_WINDOW;
|
|
56730
56959
|
if (agent.model_id) {
|
|
56731
56960
|
try {
|
|
@@ -56734,16 +56963,16 @@ async function compileContext(opts) {
|
|
|
56734
56963
|
modelContextWindow = mRow.context_window;
|
|
56735
56964
|
} catch {}
|
|
56736
56965
|
}
|
|
56737
|
-
|
|
56966
|
+
log47.info(`[context-compiler] [STEP-2] Loading scratchpad...`);
|
|
56738
56967
|
let scratchpadNotes = [];
|
|
56739
56968
|
try {
|
|
56740
56969
|
scratchpadNotes = getScratchpad(threadId);
|
|
56741
|
-
|
|
56970
|
+
log47.info(`[context-compiler] [STEP-2] \u2705 Loaded ${scratchpadNotes.length} scratchpad notes`);
|
|
56742
56971
|
} catch (err) {
|
|
56743
|
-
|
|
56972
|
+
log47.error(`[context-compiler] [STEP-2] \u274C FAILED loading scratchpad: ${JSON.stringify(err)}`);
|
|
56744
56973
|
throw err;
|
|
56745
56974
|
}
|
|
56746
|
-
|
|
56975
|
+
log47.info(`[context-compiler] [STEP-3c] Loading MCP tools...`);
|
|
56747
56976
|
const mcpToolExecutors = [];
|
|
56748
56977
|
if (effectiveMcpManager) {
|
|
56749
56978
|
try {
|
|
@@ -56754,9 +56983,13 @@ async function compileContext(opts) {
|
|
|
56754
56983
|
serverTools = effectiveMcpManager.getServerTools(server.name);
|
|
56755
56984
|
}
|
|
56756
56985
|
if (serverTools && serverTools.length > 0) {
|
|
56757
|
-
|
|
56986
|
+
log47.info(`[context-compiler] [STEP-3c] Server ${server.name}: ${serverTools.length} tools`);
|
|
56758
56987
|
for (const mcpTool of serverTools) {
|
|
56759
56988
|
const fullName = mcpToolFullName(server.name, mcpTool.name);
|
|
56989
|
+
if (!fullName || !/^[a-zA-Z0-9_-]{1,64}$/.test(fullName)) {
|
|
56990
|
+
log47.warn(`[context-compiler] Skipping MCP tool with unsupported name: "${mcpTool.name}" (server: ${server.name}, sanitized: "${fullName}")`);
|
|
56991
|
+
continue;
|
|
56992
|
+
}
|
|
56760
56993
|
mcpToolExecutors.push({
|
|
56761
56994
|
name: fullName,
|
|
56762
56995
|
description: mcpTool.description || `Tool from ${server.name}`,
|
|
@@ -56767,10 +57000,10 @@ async function compileContext(opts) {
|
|
|
56767
57000
|
});
|
|
56768
57001
|
}
|
|
56769
57002
|
} else {
|
|
56770
|
-
|
|
57003
|
+
log47.warn(`[context-compiler] [STEP-3c] Server ${server.name} has no tools (not connected yet)`);
|
|
56771
57004
|
}
|
|
56772
57005
|
}
|
|
56773
|
-
|
|
57006
|
+
log47.info(`[context-compiler] [STEP-3c] \u2705 Loaded ${mcpToolExecutors.length} MCP tools`);
|
|
56774
57007
|
if (mcpToolExecutors.length > 0) {
|
|
56775
57008
|
try {
|
|
56776
57009
|
for (const server of dbServers) {
|
|
@@ -56783,18 +57016,18 @@ async function compileContext(opts) {
|
|
|
56783
57016
|
}
|
|
56784
57017
|
}
|
|
56785
57018
|
await syncMCPToolsToFTS();
|
|
56786
|
-
|
|
57019
|
+
log47.info(`[context-compiler] [STEP-3c] \u2705 Persisted MCP tools to DB + FTS5`);
|
|
56787
57020
|
} catch (syncErr) {
|
|
56788
|
-
|
|
57021
|
+
log47.warn(`[context-compiler] [STEP-3c] \u26A0\uFE0F Failed to persist MCP tools to DB: ${syncErr.message}`);
|
|
56789
57022
|
}
|
|
56790
57023
|
}
|
|
56791
57024
|
} catch (err) {
|
|
56792
|
-
|
|
57025
|
+
log47.error(`[context-compiler] [STEP-3c] \u274C Failed: ${err.message}`);
|
|
56793
57026
|
}
|
|
56794
57027
|
} else {
|
|
56795
|
-
|
|
57028
|
+
log47.info(`[context-compiler] [STEP-3c] \u26A0\uFE0F No MCP manager, skipping MCP tools`);
|
|
56796
57029
|
}
|
|
56797
|
-
|
|
57030
|
+
log47.info(`[context-compiler] [STEP-4] Building minimal tool set`);
|
|
56798
57031
|
const config2 = { tools: {} };
|
|
56799
57032
|
const allNativeTools = createAllTools(config2);
|
|
56800
57033
|
const nativeTools = allNativeTools.map((t) => ({
|
|
@@ -56814,24 +57047,24 @@ async function compileContext(opts) {
|
|
|
56814
57047
|
}
|
|
56815
57048
|
}));
|
|
56816
57049
|
const toolsForLLM = nativeToolsForLLM;
|
|
56817
|
-
|
|
56818
|
-
|
|
56819
|
-
|
|
56820
|
-
|
|
57050
|
+
log47.info(`[context-compiler] [STEP-4] Minimal native tool set: ${filteredNativeTools.length} tools`);
|
|
57051
|
+
log47.info(`[context-compiler] [STEP-4b] MCP tools available via search_knowledge: ${mcpToolExecutors.length} (not injected)`);
|
|
57052
|
+
log47.info(`[context-compiler] [STEP-8] \u2705 Combined tools: ${allTools.length} total executors, ${toolsForLLM.length} in LLM context`);
|
|
57053
|
+
log47.info(`[context-compiler] [STEP-8b] Building skill loadout...`);
|
|
56821
57054
|
let minimalSkills = [];
|
|
56822
57055
|
let discoveredSkills = [];
|
|
56823
57056
|
try {
|
|
56824
57057
|
minimalSkills = getMinimalSkills();
|
|
56825
|
-
|
|
57058
|
+
log47.info(`[context-compiler] [STEP-8b] \u2705 Loaded ${minimalSkills.length} minimal skills`);
|
|
56826
57059
|
if (!isWorker) {
|
|
56827
57060
|
const inputForSkills = taskContext || userMessage;
|
|
56828
57061
|
const textMessage = typeof inputForSkills === "string" ? inputForSkills : Array.isArray(inputForSkills) ? inputForSkills.filter((p2) => p2.type === "text").map((p2) => p2.text).join(`
|
|
56829
57062
|
`) : String(inputForSkills);
|
|
56830
57063
|
discoveredSkills = selectSkills(textMessage);
|
|
56831
|
-
|
|
57064
|
+
log47.info(`[context-compiler] [STEP-8b] \u2705 Discovered ${discoveredSkills.length} additional skills via FTS5`);
|
|
56832
57065
|
}
|
|
56833
57066
|
} catch (err) {
|
|
56834
|
-
|
|
57067
|
+
log47.warn(`[context-compiler] [STEP-8b] \u26A0\uFE0F Skill loadout failed: ${err.message}`);
|
|
56835
57068
|
}
|
|
56836
57069
|
const skillMap = new Map;
|
|
56837
57070
|
for (const skill of minimalSkills) {
|
|
@@ -56843,20 +57076,20 @@ async function compileContext(opts) {
|
|
|
56843
57076
|
}
|
|
56844
57077
|
}
|
|
56845
57078
|
const allSkills = Array.from(skillMap.values());
|
|
56846
|
-
|
|
57079
|
+
log47.info(`[context-compiler] [STEP-9] Loading conversation history...`);
|
|
56847
57080
|
let recentMessages = [];
|
|
56848
57081
|
try {
|
|
56849
57082
|
recentMessages = getRecentMessages(threadId, KEEP_LAST_N_MESSAGES2);
|
|
56850
|
-
|
|
57083
|
+
log47.info(`[context-compiler] [STEP-9] \u2705 Loaded ${recentMessages.length} recent messages`);
|
|
56851
57084
|
} catch (err) {
|
|
56852
|
-
|
|
57085
|
+
log47.error(`[context-compiler] [STEP-9] \u274C FAILED loading history: ${JSON.stringify(err)}`);
|
|
56853
57086
|
throw err;
|
|
56854
57087
|
}
|
|
56855
57088
|
let summary = null;
|
|
56856
57089
|
try {
|
|
56857
57090
|
summary = getSummary(threadId);
|
|
56858
57091
|
} catch (err) {
|
|
56859
|
-
|
|
57092
|
+
log47.error(`[context-compiler] [STEP-9b] \u274C FAILED loading summary: ${JSON.stringify(err)}`);
|
|
56860
57093
|
throw err;
|
|
56861
57094
|
}
|
|
56862
57095
|
const totalTokens = recentMessages.reduce((sum, m2) => sum + estimateTokens(m2.content), 0);
|
|
@@ -56867,17 +57100,17 @@ async function compileContext(opts) {
|
|
|
56867
57100
|
{ role: "system", content: `[Conversation Summary]: ${summary.summary}` },
|
|
56868
57101
|
...toAPIMessages(recentMessages)
|
|
56869
57102
|
];
|
|
56870
|
-
|
|
57103
|
+
log47.info(`[context-compiler] [STEP-9c] Using summary (${summary.messages_covered} messages compressed)`);
|
|
56871
57104
|
} else {
|
|
56872
57105
|
messages = toAPIMessages(recentMessages);
|
|
56873
57106
|
}
|
|
56874
|
-
|
|
57107
|
+
log47.info(`[context-compiler] [STEP-10] Building system prompt...`);
|
|
56875
57108
|
let systemPrompt;
|
|
56876
57109
|
try {
|
|
56877
57110
|
systemPrompt = await buildSystemPromptWithProjects({ agentId, userId });
|
|
56878
|
-
|
|
57111
|
+
log47.info(`[context-compiler] [STEP-10] \u2705 System prompt built (${systemPrompt.length} chars)`);
|
|
56879
57112
|
} catch (err) {
|
|
56880
|
-
|
|
57113
|
+
log47.error(`[context-compiler] [STEP-10] \u274C FAILED building system prompt: ${JSON.stringify(err)}`);
|
|
56881
57114
|
throw err;
|
|
56882
57115
|
}
|
|
56883
57116
|
const userRow = db.query("SELECT timezone FROM users WHERE id = ?").get(userId);
|
|
@@ -56894,7 +57127,7 @@ async function compileContext(opts) {
|
|
|
56894
57127
|
**Hora**: ${hora}
|
|
56895
57128
|
**Zona horaria**: ${userTimezone}${workspaceLine}
|
|
56896
57129
|
`;
|
|
56897
|
-
|
|
57130
|
+
log47.info(`[context-compiler] [STEP-10b] \u2705 Injected current date/time: ${fecha} ${hora} (${userTimezone})`);
|
|
56898
57131
|
if (scratchpadNotes.length > 0) {
|
|
56899
57132
|
const scratchpadData = {};
|
|
56900
57133
|
for (const n of scratchpadNotes) {
|
|
@@ -56947,7 +57180,7 @@ ${skill.body}
|
|
|
56947
57180
|
}
|
|
56948
57181
|
systemPrompt += discoveredSection;
|
|
56949
57182
|
}
|
|
56950
|
-
|
|
57183
|
+
log47.info(`[context-compiler] [STEP-10d] Injected ${minimalWithBody.length} minimal skill bodies + ${discoveredOnly.length} discovered skills`);
|
|
56951
57184
|
}
|
|
56952
57185
|
}
|
|
56953
57186
|
if (isWorker && opts.taskContext) {
|
|
@@ -56970,14 +57203,14 @@ Focus ONLY on this task. Do not deviate.`;
|
|
|
56970
57203
|
systemPrompt = systemPrompt.substring(0, maxSystemPromptChars) + `
|
|
56971
57204
|
|
|
56972
57205
|
[... System prompt truncated (${originalLen} chars \u2192 ${maxSystemPromptChars} chars) ...]`;
|
|
56973
|
-
|
|
57206
|
+
log47.info(`[context-compiler] System prompt truncated: ${originalLen} \u2192 ${maxSystemPromptChars} chars`);
|
|
56974
57207
|
}
|
|
56975
57208
|
const estimatedSystemTokens = estimateTokens(systemPrompt);
|
|
56976
57209
|
const estimatedMsgTokens = messages.reduce((sum, m2) => sum + estimateTokens(typeof m2.content === "string" ? m2.content : JSON.stringify(m2.content)), 0);
|
|
56977
57210
|
const estimatedToolTokens = toolsForLLM.reduce((sum, t) => sum + estimateTokens(JSON.stringify(t)), 0);
|
|
56978
57211
|
const estimatedTotal = estimatedSystemTokens + estimatedMsgTokens + estimatedToolTokens;
|
|
56979
57212
|
const budgetPct = modelContextWindow > 0 ? Math.round(estimatedTotal / modelContextWindow * 100) : 0;
|
|
56980
|
-
|
|
57213
|
+
log47.info(`[context-compiler] \u2705 DONE: ${allTools.length} total tools, ` + `${toolsForLLM.length} selected tools, ${messages.length} messages, ` + `${allSkills.length} skills, isolated=${isWorker}, ` + `est.tokens: sys=${estimatedSystemTokens} msgs=${estimatedMsgTokens} tools=${estimatedToolTokens} ` + `total=${estimatedTotal}/${modelContextWindow} (${budgetPct}%)`);
|
|
56981
57214
|
return {
|
|
56982
57215
|
systemPrompt,
|
|
56983
57216
|
messages,
|
|
@@ -56986,7 +57219,7 @@ Focus ONLY on this task. Do not deviate.`;
|
|
|
56986
57219
|
skills: allSkills
|
|
56987
57220
|
};
|
|
56988
57221
|
}
|
|
56989
|
-
var
|
|
57222
|
+
var log47, KEEP_LAST_N_MESSAGES2 = 30, DEFAULT_CONTEXT_WINDOW = 250000, COMPACT_RATIO = 0.8, MAX_SYSTEM_PROMPT_CHARS_CAP = 128000, MINIMAL_TOOLS, MINIMAL_SKILL_NAMES2;
|
|
56990
57223
|
var init_context_compiler = __esm(() => {
|
|
56991
57224
|
init_sqlite();
|
|
56992
57225
|
init_logger();
|
|
@@ -56999,7 +57232,7 @@ var init_context_compiler = __esm(() => {
|
|
|
56999
57232
|
init_tools();
|
|
57000
57233
|
init_onboarding();
|
|
57001
57234
|
init_tool_sync();
|
|
57002
|
-
|
|
57235
|
+
log47 = logger.child("context-compiler");
|
|
57003
57236
|
MINIMAL_TOOLS = new Set([
|
|
57004
57237
|
"save_note",
|
|
57005
57238
|
"notify",
|
|
@@ -57402,6 +57635,157 @@ var init_tool_runtime = __esm(() => {
|
|
|
57402
57635
|
]);
|
|
57403
57636
|
});
|
|
57404
57637
|
|
|
57638
|
+
// packages/core/src/utils/crypto.ts
|
|
57639
|
+
import * as crypto2 from "crypto";
|
|
57640
|
+
function hashString(input) {
|
|
57641
|
+
return crypto2.createHash("sha256").update(input).digest("hex");
|
|
57642
|
+
}
|
|
57643
|
+
function hashObject(obj2) {
|
|
57644
|
+
return hashString(JSON.stringify(obj2));
|
|
57645
|
+
}
|
|
57646
|
+
var init_crypto2 = () => {};
|
|
57647
|
+
|
|
57648
|
+
// packages/core/src/agent/stuck-loop.ts
|
|
57649
|
+
class StuckLoopDetector {
|
|
57650
|
+
log = logger.child("stuck-loop");
|
|
57651
|
+
history = new Map;
|
|
57652
|
+
progressHistory = new Map;
|
|
57653
|
+
maxHistoryPerSession = 50;
|
|
57654
|
+
triggerThreshold = 3;
|
|
57655
|
+
progressThreshold = 3;
|
|
57656
|
+
constructor(_config) {}
|
|
57657
|
+
recordToolCall(sessionId, toolName, args, error4) {
|
|
57658
|
+
let sessionHistory = this.history.get(sessionId);
|
|
57659
|
+
if (!sessionHistory) {
|
|
57660
|
+
sessionHistory = [];
|
|
57661
|
+
this.history.set(sessionId, sessionHistory);
|
|
57662
|
+
}
|
|
57663
|
+
const record2 = {
|
|
57664
|
+
toolName,
|
|
57665
|
+
argsHash: hashObject(args),
|
|
57666
|
+
errorMessage: error4,
|
|
57667
|
+
timestamp: Date.now()
|
|
57668
|
+
};
|
|
57669
|
+
sessionHistory.push(record2);
|
|
57670
|
+
if (sessionHistory.length > this.maxHistoryPerSession) {
|
|
57671
|
+
sessionHistory.shift();
|
|
57672
|
+
}
|
|
57673
|
+
this.log.debug(`Recorded tool call: ${toolName} for session ${sessionId}`);
|
|
57674
|
+
}
|
|
57675
|
+
check(sessionId) {
|
|
57676
|
+
const sessionHistory = this.history.get(sessionId) ?? [];
|
|
57677
|
+
if (sessionHistory.length < this.triggerThreshold) {
|
|
57678
|
+
return { detected: false, toolName: "", count: 0, kind: "loop" };
|
|
57679
|
+
}
|
|
57680
|
+
const recent = sessionHistory.slice(-10);
|
|
57681
|
+
const counts = new Map;
|
|
57682
|
+
for (const record2 of recent) {
|
|
57683
|
+
const key = `${record2.toolName}:${record2.argsHash}`;
|
|
57684
|
+
const existing = counts.get(key);
|
|
57685
|
+
if (existing) {
|
|
57686
|
+
existing.count++;
|
|
57687
|
+
if (record2.errorMessage) {
|
|
57688
|
+
existing.error = record2.errorMessage;
|
|
57689
|
+
}
|
|
57690
|
+
} else {
|
|
57691
|
+
counts.set(key, { count: 1, error: record2.errorMessage });
|
|
57692
|
+
}
|
|
57693
|
+
}
|
|
57694
|
+
for (const [key, data] of counts) {
|
|
57695
|
+
if (data.count >= this.triggerThreshold && data.error) {
|
|
57696
|
+
const toolName = key.split(":")[0] ?? "unknown";
|
|
57697
|
+
this.log.warn(`Stuck loop detected: ${toolName} called ${data.count} times with same args and error`);
|
|
57698
|
+
return {
|
|
57699
|
+
detected: true,
|
|
57700
|
+
toolName,
|
|
57701
|
+
count: data.count,
|
|
57702
|
+
lastError: data.error,
|
|
57703
|
+
kind: "loop"
|
|
57704
|
+
};
|
|
57705
|
+
}
|
|
57706
|
+
}
|
|
57707
|
+
return { detected: false, toolName: "", count: 0, kind: "loop" };
|
|
57708
|
+
}
|
|
57709
|
+
recordProgress(sessionId, progressHash) {
|
|
57710
|
+
let sessionProgress = this.progressHistory.get(sessionId);
|
|
57711
|
+
if (!sessionProgress) {
|
|
57712
|
+
sessionProgress = [];
|
|
57713
|
+
this.progressHistory.set(sessionId, sessionProgress);
|
|
57714
|
+
}
|
|
57715
|
+
sessionProgress.push({ hash: progressHash, timestamp: Date.now() });
|
|
57716
|
+
if (sessionProgress.length > this.maxHistoryPerSession) {
|
|
57717
|
+
sessionProgress.shift();
|
|
57718
|
+
}
|
|
57719
|
+
this.log.debug(`Recorded progress hash for session ${sessionId}: ${progressHash}`);
|
|
57720
|
+
}
|
|
57721
|
+
checkProgress(sessionId, threshold) {
|
|
57722
|
+
const sessionProgress = this.progressHistory.get(sessionId) ?? [];
|
|
57723
|
+
const required2 = threshold ?? this.progressThreshold;
|
|
57724
|
+
if (sessionProgress.length < required2) {
|
|
57725
|
+
return { detected: false, toolName: "", count: 0, kind: "stall" };
|
|
57726
|
+
}
|
|
57727
|
+
const recent = sessionProgress.slice(-required2);
|
|
57728
|
+
const firstHash = recent[0]?.hash;
|
|
57729
|
+
const allSame = recent.every((r) => r.hash === firstHash);
|
|
57730
|
+
if (allSame && firstHash) {
|
|
57731
|
+
this.log.warn(`Stall detected: no progress for ${required2} checks (hash ${firstHash})`);
|
|
57732
|
+
return {
|
|
57733
|
+
detected: true,
|
|
57734
|
+
toolName: "NO_PROGRESS",
|
|
57735
|
+
count: required2,
|
|
57736
|
+
kind: "stall"
|
|
57737
|
+
};
|
|
57738
|
+
}
|
|
57739
|
+
return { detected: false, toolName: "", count: 0, kind: "stall" };
|
|
57740
|
+
}
|
|
57741
|
+
clear(sessionId) {
|
|
57742
|
+
this.history.delete(sessionId);
|
|
57743
|
+
this.progressHistory.delete(sessionId);
|
|
57744
|
+
this.log.debug(`Cleared stuck loop history for session ${sessionId}`);
|
|
57745
|
+
}
|
|
57746
|
+
prune(maxAgeMs = 30 * 60 * 1000) {
|
|
57747
|
+
const now = Date.now();
|
|
57748
|
+
let pruned = 0;
|
|
57749
|
+
for (const [sessionId, history] of this.history) {
|
|
57750
|
+
const filtered = history.filter((r) => now - r.timestamp < maxAgeMs);
|
|
57751
|
+
if (filtered.length === 0) {
|
|
57752
|
+
this.history.delete(sessionId);
|
|
57753
|
+
pruned++;
|
|
57754
|
+
} else if (filtered.length !== history.length) {
|
|
57755
|
+
this.history.set(sessionId, filtered);
|
|
57756
|
+
}
|
|
57757
|
+
}
|
|
57758
|
+
for (const [sessionId, history] of this.progressHistory) {
|
|
57759
|
+
const filtered = history.filter((r) => now - r.timestamp < maxAgeMs);
|
|
57760
|
+
if (filtered.length === 0) {
|
|
57761
|
+
this.progressHistory.delete(sessionId);
|
|
57762
|
+
pruned++;
|
|
57763
|
+
} else if (filtered.length !== history.length) {
|
|
57764
|
+
this.progressHistory.set(sessionId, filtered);
|
|
57765
|
+
}
|
|
57766
|
+
}
|
|
57767
|
+
return pruned;
|
|
57768
|
+
}
|
|
57769
|
+
}
|
|
57770
|
+
function createStuckLoopDetector(config2) {
|
|
57771
|
+
return new StuckLoopDetector(config2);
|
|
57772
|
+
}
|
|
57773
|
+
function getInterventionMessage(state) {
|
|
57774
|
+
if (!state.detected)
|
|
57775
|
+
return "";
|
|
57776
|
+
if (state.kind === "stall") {
|
|
57777
|
+
return `WARNING: Has estado sin avanzar durante ${state.count} ciclos consecutivos. Revisa tu plan, intenta una herramienta diferente o pide aclaraci\xF3n al usuario en lugar de repetir la misma secuencia.`;
|
|
57778
|
+
}
|
|
57779
|
+
if (state.count >= 4) {
|
|
57780
|
+
return `CRITICAL: Has llamado ${state.toolName} ${state.count} veces con los mismos argumentos y sigue fallando con: "${state.lastError}". El usuario ser\xE1 notificado. Debes cambiar completamente de estrategia o pedir ayuda.`;
|
|
57781
|
+
}
|
|
57782
|
+
return `WARNING: Has llamado ${state.toolName} ${state.count} veces con los mismos argumentos y sigue fallando. Debes probar un enfoque diferente en lugar de repetir la misma acci\xF3n.`;
|
|
57783
|
+
}
|
|
57784
|
+
var init_stuck_loop = __esm(() => {
|
|
57785
|
+
init_logger();
|
|
57786
|
+
init_crypto2();
|
|
57787
|
+
});
|
|
57788
|
+
|
|
57405
57789
|
// packages/core/src/agent/agent-loop.ts
|
|
57406
57790
|
var exports_agent_loop = {};
|
|
57407
57791
|
__export(exports_agent_loop, {
|
|
@@ -57420,9 +57804,13 @@ async function* runAgent(opts) {
|
|
|
57420
57804
|
throw new Error(`Agent not found: ${opts.agentId}`);
|
|
57421
57805
|
const agentName = agent.name || opts.agentId;
|
|
57422
57806
|
const maxIterations = agent.max_iterations || 10;
|
|
57807
|
+
const maxWallClockMs = agent.max_wall_clock_ms || DEFAULT_MAX_WALL_CLOCK_MS;
|
|
57808
|
+
const wallClockDeadline = Date.now() + maxWallClockMs;
|
|
57809
|
+
const stuckDetector = createStuckLoopDetector(loadConfig());
|
|
57810
|
+
let stuckState;
|
|
57423
57811
|
const providerCfg = await resolveProviderConfig(agent.provider_id || "openai", agent.model_id || "gpt-4o-mini");
|
|
57424
57812
|
const cleanModel = providerCfg.model.replace(new RegExp(`^${providerCfg.provider}\\/`), "");
|
|
57425
|
-
|
|
57813
|
+
log48.info(`[agent-loop] Starting: agent=${agentName} thread=${opts.threadId} provider=${providerCfg.provider}/${cleanModel}`);
|
|
57426
57814
|
emitCanvas("canvas:node_update", {
|
|
57427
57815
|
nodeId: opts.agentId,
|
|
57428
57816
|
changes: { status: "thinking" }
|
|
@@ -57441,6 +57829,17 @@ async function* runAgent(opts) {
|
|
|
57441
57829
|
taskContext: opts.taskContext,
|
|
57442
57830
|
userId: opts.userId
|
|
57443
57831
|
});
|
|
57832
|
+
if (opts.extraTools?.length) {
|
|
57833
|
+
const existingNames = new Set(ctx.tools.map((t) => t.function?.name));
|
|
57834
|
+
for (const tool of opts.extraTools) {
|
|
57835
|
+
const name = tool.function?.name || tool.name;
|
|
57836
|
+
if (name && !existingNames.has(name)) {
|
|
57837
|
+
ctx.tools.push(tool);
|
|
57838
|
+
existingNames.add(name);
|
|
57839
|
+
log48.info(`[agent-loop] Force-injected tool into loadout: ${name}`);
|
|
57840
|
+
}
|
|
57841
|
+
}
|
|
57842
|
+
}
|
|
57444
57843
|
const systemPrompt = opts.systemPromptOverride || ctx.systemPrompt;
|
|
57445
57844
|
let messages = [
|
|
57446
57845
|
{ role: "system", content: systemPrompt },
|
|
@@ -57456,17 +57855,29 @@ async function* runAgent(opts) {
|
|
|
57456
57855
|
let lastToolSignature = "";
|
|
57457
57856
|
let consecutiveRepeat = 0;
|
|
57458
57857
|
let loopDetected = false;
|
|
57858
|
+
let idleIterations = 0;
|
|
57859
|
+
const PROGRESS_TOOLS = new Set(["browser_type", "browser_click", "browser_navigate"]);
|
|
57459
57860
|
while (iterations < maxIterations) {
|
|
57460
57861
|
if (opts.signal?.aborted) {
|
|
57461
|
-
|
|
57862
|
+
log48.info(`[agent-loop] Aborted by signal at iteration ${iterations}`);
|
|
57462
57863
|
finalContent = "Generaci\xF3n detenida.";
|
|
57463
57864
|
break;
|
|
57464
57865
|
}
|
|
57866
|
+
if (Date.now() > wallClockDeadline) {
|
|
57867
|
+
log48.warn(`[agent-loop] Wall-clock timeout exceeded (${maxWallClockMs}ms). Breaking.`);
|
|
57868
|
+
finalContent = "La tarea tom\xF3 demasiado tiempo. Te sugiero dividirla en pasos m\xE1s peque\xF1os o darme m\xE1s detalles para continuar.";
|
|
57869
|
+
break;
|
|
57870
|
+
}
|
|
57465
57871
|
iterations++;
|
|
57872
|
+
let streamedThisCall = false;
|
|
57466
57873
|
const response = await callLLM({
|
|
57467
57874
|
...providerCfg,
|
|
57468
57875
|
messages: clearOldToolResults(messages),
|
|
57469
|
-
tools: ctx.tools.length > 0 ? ctx.tools : undefined
|
|
57876
|
+
tools: ctx.tools.length > 0 ? ctx.tools : undefined,
|
|
57877
|
+
onToken: opts.onToken ? (token) => {
|
|
57878
|
+
streamedThisCall = true;
|
|
57879
|
+
opts.onToken?.(token);
|
|
57880
|
+
} : undefined
|
|
57470
57881
|
});
|
|
57471
57882
|
if (response.usage) {
|
|
57472
57883
|
totalInputTokens += response.usage.input_tokens;
|
|
@@ -57475,7 +57886,7 @@ async function* runAgent(opts) {
|
|
|
57475
57886
|
const agentMsg = { content: response.content };
|
|
57476
57887
|
if (response.tool_calls?.length)
|
|
57477
57888
|
agentMsg.tool_calls = response.tool_calls;
|
|
57478
|
-
yield { agent: { messages: [agentMsg] } };
|
|
57889
|
+
yield { agent: { messages: [agentMsg], streamed: streamedThisCall } };
|
|
57479
57890
|
if (opts.onStep && response.content) {
|
|
57480
57891
|
await opts.onStep({ type: "text", message: response.content });
|
|
57481
57892
|
}
|
|
@@ -57529,9 +57940,9 @@ async function* runAgent(opts) {
|
|
|
57529
57940
|
const toolResultJS = batchResult.result;
|
|
57530
57941
|
const toolMs = batchResult.durationMs;
|
|
57531
57942
|
const toolResultLLM = formatToolResult(toolResultJS, cleanModel);
|
|
57532
|
-
|
|
57943
|
+
log48.info(`[agent-loop] Tool ${toolName} completed in ${toolMs}ms`);
|
|
57533
57944
|
const resultPreview = toolResultLLM.length > 500 ? toolResultLLM.substring(0, 500) + `\u2026 (+${toolResultLLM.length - 500} chars)` : toolResultLLM;
|
|
57534
|
-
|
|
57945
|
+
log48.info(`[agent-loop] Tool result [${toolName}]: ${resultPreview}`);
|
|
57535
57946
|
const textMessage = typeof opts.userMessage === "string" ? opts.userMessage : Array.isArray(opts.userMessage) ? opts.userMessage.filter((p2) => p2.type === "text").map((p2) => p2.text).join(`
|
|
57536
57947
|
`) : String(opts.userMessage);
|
|
57537
57948
|
const cleanMessage = textMessage.replace(/^\[Timestamp:.*?\]\n/, "");
|
|
@@ -57555,6 +57966,8 @@ async function* runAgent(opts) {
|
|
|
57555
57966
|
content: toolResultLLM,
|
|
57556
57967
|
tool_call_id: tc.id
|
|
57557
57968
|
});
|
|
57969
|
+
const errorMessage = toolResultLLM.startsWith("[Tool Error]") ? toolResultLLM : undefined;
|
|
57970
|
+
stuckDetector.recordToolCall(opts.threadId, toolName, tc.function.arguments, errorMessage);
|
|
57558
57971
|
if (toolName === "search_knowledge") {
|
|
57559
57972
|
try {
|
|
57560
57973
|
const result = toolResultJS;
|
|
@@ -57569,7 +57982,7 @@ async function* runAgent(opts) {
|
|
|
57569
57982
|
const altName = found.name.includes(".") ? found.name.replace(/\./g, "_") : found.name.replace(/_/g, ".");
|
|
57570
57983
|
nativeTool = ctx.allTools.find((t) => t.name === altName);
|
|
57571
57984
|
if (nativeTool) {
|
|
57572
|
-
|
|
57985
|
+
log48.info(`[agent-loop] Resolved legacy tool name "${found.name}" \u2192 "${nativeTool.name}"`);
|
|
57573
57986
|
}
|
|
57574
57987
|
}
|
|
57575
57988
|
if (nativeTool) {
|
|
@@ -57581,17 +57994,17 @@ async function* runAgent(opts) {
|
|
|
57581
57994
|
parameters: nativeTool.parameters ?? { type: "object", properties: {} }
|
|
57582
57995
|
}
|
|
57583
57996
|
});
|
|
57584
|
-
|
|
57997
|
+
log48.info(`[agent-loop] Injected discovered native tool into loadout: ${nativeTool.name}`);
|
|
57585
57998
|
currentToolNames.add(found.name);
|
|
57586
57999
|
injectedTools.push(nativeTool.name);
|
|
57587
58000
|
} else {
|
|
57588
|
-
|
|
58001
|
+
log48.warn(`[agent-loop] search_knowledge returned tool "${found.name}" but no matching executor found in allTools`);
|
|
57589
58002
|
}
|
|
57590
58003
|
}
|
|
57591
58004
|
}
|
|
57592
58005
|
for (const found of foundMcpTools) {
|
|
57593
58006
|
const mcpFullName = found.full_name || found.id;
|
|
57594
|
-
|
|
58007
|
+
log48.debug(`[agent-loop] MCP discovery candidate: tool_name="${found.tool_name}", full_name="${found.full_name}", id="${found.id}", resolved="${mcpFullName}"`);
|
|
57595
58008
|
if (!currentToolNames.has(mcpFullName)) {
|
|
57596
58009
|
const mcpTool = ctx.allTools.find((t) => t.name === mcpFullName);
|
|
57597
58010
|
if (mcpTool) {
|
|
@@ -57603,10 +58016,10 @@ async function* runAgent(opts) {
|
|
|
57603
58016
|
parameters: mcpTool.parameters ?? { type: "object", properties: {} }
|
|
57604
58017
|
}
|
|
57605
58018
|
});
|
|
57606
|
-
|
|
58019
|
+
log48.info(`[agent-loop] Injected discovered MCP tool into loadout: ${mcpTool.name}`);
|
|
57607
58020
|
currentToolNames.add(mcpFullName);
|
|
57608
58021
|
} else {
|
|
57609
|
-
|
|
58022
|
+
log48.warn(`[agent-loop] MCP tool "${mcpFullName}" not found in allTools (available MCP: ${ctx.allTools.filter((t) => t.name.includes("__")).map((t) => t.name).join(", ")})`);
|
|
57610
58023
|
}
|
|
57611
58024
|
}
|
|
57612
58025
|
}
|
|
@@ -57644,16 +58057,16 @@ ${s2.body}`).join(`
|
|
|
57644
58057
|
|
|
57645
58058
|
--- SKILL INSTRUCTIONS (Auto-loaded) ---
|
|
57646
58059
|
${newSkillSection}`;
|
|
57647
|
-
|
|
58060
|
+
log48.info(`[agent-loop] Injected ${newSkills.length} skill(s) for tools: ${newSkills.map((s2) => s2.name).join(", ")}`);
|
|
57648
58061
|
}
|
|
57649
58062
|
}
|
|
57650
58063
|
}
|
|
57651
58064
|
} catch (skillErr) {
|
|
57652
|
-
|
|
58065
|
+
log48.warn(`[agent-loop] Failed to inject skills for tools: ${skillErr.message}`);
|
|
57653
58066
|
}
|
|
57654
58067
|
}
|
|
57655
58068
|
} catch (err) {
|
|
57656
|
-
|
|
58069
|
+
log48.warn(`[agent-loop] search_knowledge tool injection failed: ${err.message}`);
|
|
57657
58070
|
}
|
|
57658
58071
|
try {
|
|
57659
58072
|
const result = toolResultJS;
|
|
@@ -57683,19 +58096,19 @@ ${section}`);
|
|
|
57683
58096
|
const lastMsg = messages[messages.length - 1];
|
|
57684
58097
|
if (lastMsg?.role === "tool") {
|
|
57685
58098
|
lastMsg.content += extras.join("");
|
|
57686
|
-
|
|
58099
|
+
log48.info(`[agent-loop] Enriched search_knowledge result with ${foundSkills.length} skill(s) and ${foundPlaybook.length} rule(s)`);
|
|
57687
58100
|
}
|
|
57688
58101
|
}
|
|
57689
58102
|
}
|
|
57690
58103
|
} catch (err) {
|
|
57691
|
-
|
|
58104
|
+
log48.warn(`[agent-loop] search_knowledge enrichment failed: ${err.message}`);
|
|
57692
58105
|
}
|
|
57693
58106
|
}
|
|
57694
58107
|
const sig = `${toolName}:${JSON.stringify(tc.function.arguments)}`;
|
|
57695
58108
|
if (sig === lastToolSignature) {
|
|
57696
58109
|
consecutiveRepeat++;
|
|
57697
58110
|
if (consecutiveRepeat >= 2) {
|
|
57698
|
-
|
|
58111
|
+
log48.warn(`[agent-loop] Loop detected: "${toolName}" x${consecutiveRepeat + 1} with same args. Breaking.`);
|
|
57699
58112
|
finalContent = "No pude completar la tarea porque no encontr\xE9 las herramientas necesarias para ello.";
|
|
57700
58113
|
loopDetected = true;
|
|
57701
58114
|
}
|
|
@@ -57706,13 +58119,52 @@ ${section}`);
|
|
|
57706
58119
|
}
|
|
57707
58120
|
if (loopDetected)
|
|
57708
58121
|
break;
|
|
58122
|
+
stuckState = stuckDetector.check(opts.threadId);
|
|
58123
|
+
if (stuckState.detected) {
|
|
58124
|
+
const intervention = getInterventionMessage(stuckState);
|
|
58125
|
+
log48.warn(`[agent-loop] ${intervention}`);
|
|
58126
|
+
if (stuckState.count >= 4) {
|
|
58127
|
+
finalContent = intervention;
|
|
58128
|
+
loopDetected = true;
|
|
58129
|
+
emitCanvas("canvas:node_update", {
|
|
58130
|
+
nodeId: opts.agentId,
|
|
58131
|
+
changes: { status: "stuck", currentTool: stuckState.toolName }
|
|
58132
|
+
});
|
|
58133
|
+
break;
|
|
58134
|
+
} else {
|
|
58135
|
+
messages.push({
|
|
58136
|
+
role: "user",
|
|
58137
|
+
content: intervention
|
|
58138
|
+
});
|
|
58139
|
+
}
|
|
58140
|
+
}
|
|
58141
|
+
const hadProgress = toolResults.some((r) => PROGRESS_TOOLS.has(r.toolName) && !String(r.result).startsWith("[Tool Error]"));
|
|
58142
|
+
if (hadProgress) {
|
|
58143
|
+
idleIterations = 0;
|
|
58144
|
+
} else if (toolResults.length > 0) {
|
|
58145
|
+
idleIterations++;
|
|
58146
|
+
}
|
|
58147
|
+
if (idleIterations >= 3 && idleIterations < 5) {
|
|
58148
|
+
const stallMsg = "ADVERTENCIA: Llevas varios pasos sin modificar la p\xE1gina. Si ya completaste el formulario, responde al usuario. Si no, avanza con browser_type/browser_click en lugar de seguir inspeccionando.";
|
|
58149
|
+
log48.warn(`[agent-loop] ${stallMsg}`);
|
|
58150
|
+
messages.push({ role: "user", content: stallMsg });
|
|
58151
|
+
} else if (idleIterations >= 5) {
|
|
58152
|
+
const stallMsg = "No logr\xE9 avanzar en el formulario despu\xE9s de varios intentos. Puede que la p\xE1gina no sea compatible o que falten instrucciones. Te sugiero revisar la URL o darme m\xE1s detalles.";
|
|
58153
|
+
log48.warn(`[agent-loop] Stall break: ${stallMsg}`);
|
|
58154
|
+
finalContent = stallMsg;
|
|
58155
|
+
emitCanvas("canvas:node_update", {
|
|
58156
|
+
nodeId: opts.agentId,
|
|
58157
|
+
changes: { status: "stuck", currentTool: "NO_PROGRESS" }
|
|
58158
|
+
});
|
|
58159
|
+
break;
|
|
58160
|
+
}
|
|
57709
58161
|
emitCanvas("canvas:node_update", {
|
|
57710
58162
|
nodeId: opts.agentId,
|
|
57711
58163
|
changes: { status: "thinking", currentTool: null }
|
|
57712
58164
|
});
|
|
57713
58165
|
}
|
|
57714
58166
|
if (!finalContent) {
|
|
57715
|
-
|
|
58167
|
+
log48.info(`[agent-loop] Max iterations hit with no text response \u2014 requesting synthesis (isolated=${!!opts.isolated})`);
|
|
57716
58168
|
try {
|
|
57717
58169
|
messages.push({
|
|
57718
58170
|
role: "user",
|
|
@@ -57733,7 +58185,7 @@ ${section}`);
|
|
|
57733
58185
|
}
|
|
57734
58186
|
yield { agent: { messages: [{ content: finalContent }] } };
|
|
57735
58187
|
} catch (err) {
|
|
57736
|
-
|
|
58188
|
+
log48.warn(`[agent-loop] Synthesis call failed: ${err.message}`);
|
|
57737
58189
|
finalContent = "He completado las tareas solicitadas.";
|
|
57738
58190
|
if (!opts.isolated) {
|
|
57739
58191
|
addMessage(opts.threadId, "assistant", finalContent);
|
|
@@ -57768,7 +58220,7 @@ ${section}`);
|
|
|
57768
58220
|
durationMs,
|
|
57769
58221
|
tokensUsed: totalInputTokens + totalOutputTokens
|
|
57770
58222
|
});
|
|
57771
|
-
|
|
58223
|
+
log48.info(`[agent-loop] Done: agent=${agentName} iterations=${iterations} ` + `tokens=${totalInputTokens + totalOutputTokens} elapsed=${durationMs}ms`);
|
|
57772
58224
|
}
|
|
57773
58225
|
async function runAgentIsolated(opts) {
|
|
57774
58226
|
let lastContent = "";
|
|
@@ -57801,16 +58253,16 @@ class AgentLoop {
|
|
|
57801
58253
|
channel: config2.configurable?.channel ? (config2.configurable?.channel).split(":")[0] : null,
|
|
57802
58254
|
channelUserId: config2.configurable?.thread_id
|
|
57803
58255
|
});
|
|
57804
|
-
|
|
58256
|
+
log48.info(`[AgentLoop.stream] MCP Manager available: ${this.mcpManager !== null}`);
|
|
57805
58257
|
if (this.mcpManager) {
|
|
57806
58258
|
try {
|
|
57807
58259
|
const servers = this.mcpManager.listServers?.() || [];
|
|
57808
|
-
|
|
58260
|
+
log48.info(`[AgentLoop.stream] MCP servers: ${servers.length} registered`);
|
|
57809
58261
|
for (const s2 of servers) {
|
|
57810
|
-
|
|
58262
|
+
log48.info(` - ${s2.name}: ${s2.status} (${s2.tools?.length || 0} tools)`);
|
|
57811
58263
|
}
|
|
57812
58264
|
} catch (e) {
|
|
57813
|
-
|
|
58265
|
+
log48.warn(`[AgentLoop.stream] Failed to list MCP servers: ${e.message}`);
|
|
57814
58266
|
}
|
|
57815
58267
|
}
|
|
57816
58268
|
const lastUserMsg = [...input.messages].reverse().find((m2) => m2.role === "user");
|
|
@@ -57826,7 +58278,10 @@ class AgentLoop {
|
|
|
57826
58278
|
systemPromptOverride,
|
|
57827
58279
|
mcpManager: this.mcpManager,
|
|
57828
58280
|
userId,
|
|
57829
|
-
signal: config2.signal
|
|
58281
|
+
signal: config2.signal,
|
|
58282
|
+
onToken: config2.onToken,
|
|
58283
|
+
onStep: config2.onStep,
|
|
58284
|
+
extraTools: config2.extraTools
|
|
57830
58285
|
});
|
|
57831
58286
|
}
|
|
57832
58287
|
_resolveCoordinatorId() {
|
|
@@ -57841,9 +58296,9 @@ function buildAgentLoop(opts = {}) {
|
|
|
57841
58296
|
_agentLoop = new AgentLoop;
|
|
57842
58297
|
if (opts.mcpManager) {
|
|
57843
58298
|
_agentLoop.setMCPManager(opts.mcpManager);
|
|
57844
|
-
|
|
58299
|
+
log48.info("[buildAgentLoop] MCP Manager set successfully");
|
|
57845
58300
|
} else {
|
|
57846
|
-
|
|
58301
|
+
log48.warn("[buildAgentLoop] No MCP Manager provided, agent will not have MCP tools");
|
|
57847
58302
|
}
|
|
57848
58303
|
return _agentLoop;
|
|
57849
58304
|
}
|
|
@@ -57851,7 +58306,7 @@ async function rebuildAgentLoop(opts = {}) {
|
|
|
57851
58306
|
_agentLoop = null;
|
|
57852
58307
|
return buildAgentLoop(opts);
|
|
57853
58308
|
}
|
|
57854
|
-
var
|
|
58309
|
+
var log48, DEFAULT_MAX_WALL_CLOCK_MS, _agentLoop = null;
|
|
57855
58310
|
var init_agent_loop = __esm(() => {
|
|
57856
58311
|
init_logger();
|
|
57857
58312
|
init_sqlite();
|
|
@@ -57865,11 +58320,13 @@ var init_agent_loop = __esm(() => {
|
|
|
57865
58320
|
init_onboarding();
|
|
57866
58321
|
init_loader();
|
|
57867
58322
|
init_tool_runtime();
|
|
57868
|
-
|
|
58323
|
+
init_stuck_loop();
|
|
58324
|
+
log48 = logger.child("agent-loop");
|
|
58325
|
+
DEFAULT_MAX_WALL_CLOCK_MS = 5 * 60 * 1000;
|
|
57869
58326
|
});
|
|
57870
58327
|
|
|
57871
58328
|
// packages/core/src/tools/agents/index.ts
|
|
57872
|
-
import
|
|
58329
|
+
import crypto3 from "crypto";
|
|
57873
58330
|
function createTools5() {
|
|
57874
58331
|
return [
|
|
57875
58332
|
memoryWriteTool,
|
|
@@ -57888,13 +58345,13 @@ function createTools5() {
|
|
|
57888
58345
|
busReadTool
|
|
57889
58346
|
];
|
|
57890
58347
|
}
|
|
57891
|
-
var
|
|
58348
|
+
var log49, memoryWriteTool, memoryReadTool, memoryListTool, memorySearchTool, memoryDeleteTool, agentCreateTool, agentFindTool, agentArchiveTool, taskDelegateTool, taskDelegateCodeTool, taskStatusTool, busPublishTool, busReadTool;
|
|
57892
58349
|
var init_agents = __esm(() => {
|
|
57893
58350
|
init_sqlite();
|
|
57894
58351
|
init_logger();
|
|
57895
58352
|
init_agent_bus();
|
|
57896
58353
|
init_get_available_models();
|
|
57897
|
-
|
|
58354
|
+
log49 = logger.child("agents");
|
|
57898
58355
|
memoryWriteTool = {
|
|
57899
58356
|
name: "memory_write",
|
|
57900
58357
|
description: "Store information in persistent long-term memory. Spanish: guardar memoria, recordar, guardar dato, memoria persistente",
|
|
@@ -58089,7 +58546,7 @@ var init_agents = __esm(() => {
|
|
|
58089
58546
|
};
|
|
58090
58547
|
}
|
|
58091
58548
|
try {
|
|
58092
|
-
const agentId =
|
|
58549
|
+
const agentId = crypto3.randomUUID().replace(/-/g, "").slice(0, 16);
|
|
58093
58550
|
db.query(`
|
|
58094
58551
|
INSERT INTO agents (id, user_id, name, description, system_prompt, tools_json, role, status, parent_id, provider_id, model_id, tone, max_iterations, workspace)
|
|
58095
58552
|
VALUES (?, ?, ?, ?, ?, ?, 'worker', 'idle', ?, ?, ?, ?, ?, ?)
|
|
@@ -58199,7 +58656,7 @@ var init_agents = __esm(() => {
|
|
|
58199
58656
|
}
|
|
58200
58657
|
const taskName = taskDescription.slice(0, 60);
|
|
58201
58658
|
agentBus.notifyTaskStarted(workerId, worker.name, 0, taskName, "");
|
|
58202
|
-
|
|
58659
|
+
log49.info(`[task_delegate] Delegating to ${worker.name} (${workerId})`);
|
|
58203
58660
|
try {
|
|
58204
58661
|
const { runAgentIsolated: runAgentIsolated2 } = await Promise.resolve().then(() => (init_agent_loop(), exports_agent_loop));
|
|
58205
58662
|
const threadId = `task-${Date.now()}-${workerId}`;
|
|
@@ -58685,7 +59142,7 @@ var init_canvas_manager = __esm(() => {
|
|
|
58685
59142
|
|
|
58686
59143
|
// packages/core/src/canvas/a2ui-tools.ts
|
|
58687
59144
|
function createA2UISurfaceTool(_config) {
|
|
58688
|
-
const
|
|
59145
|
+
const log50 = logger.child("a2ui-surface");
|
|
58689
59146
|
return {
|
|
58690
59147
|
name: "a2ui_create_surface",
|
|
58691
59148
|
description: "Create an A2UI v0.9 surface on the user's canvas for rendering rich interactive UIs",
|
|
@@ -58737,7 +59194,7 @@ function createA2UISurfaceTool(_config) {
|
|
|
58737
59194
|
})();
|
|
58738
59195
|
if (!canvasManager.isSessionConnected(sessionId)) {
|
|
58739
59196
|
const connected = canvasManager.getConnectedSessions();
|
|
58740
|
-
|
|
59197
|
+
log50.warn(`No canvas sessions connected. Rendering to ${sessionId} anyway. Available: ${connected.join(", ")}`);
|
|
58741
59198
|
}
|
|
58742
59199
|
await canvasManager.sendA2UIMessage(sessionId, "a2ui:createSurface", {
|
|
58743
59200
|
surfaceId: params.surfaceId,
|
|
@@ -58745,7 +59202,7 @@ function createA2UISurfaceTool(_config) {
|
|
|
58745
59202
|
theme: params.theme ?? {},
|
|
58746
59203
|
sendDataModel: params.sendDataModel ?? false
|
|
58747
59204
|
});
|
|
58748
|
-
|
|
59205
|
+
log50.info(`Created A2UI surface '${params.surfaceId}' on session ${sessionId}`);
|
|
58749
59206
|
return JSON.stringify({
|
|
58750
59207
|
status: "created",
|
|
58751
59208
|
surfaceId: params.surfaceId,
|
|
@@ -58755,7 +59212,7 @@ function createA2UISurfaceTool(_config) {
|
|
|
58755
59212
|
};
|
|
58756
59213
|
}
|
|
58757
59214
|
function createA2UIUpdateComponentsTool(_config) {
|
|
58758
|
-
const
|
|
59215
|
+
const log50 = logger.child("a2ui-components");
|
|
58759
59216
|
return {
|
|
58760
59217
|
name: "a2ui_update_components",
|
|
58761
59218
|
description: `Send A2UI v0.9 components to an existing surface. Components are a FLAT list with ID references (adjacency list).
|
|
@@ -58826,7 +59283,7 @@ Root component: usar id="root" expl\xEDcito.`,
|
|
|
58826
59283
|
surfaceId: params.surfaceId,
|
|
58827
59284
|
components: params.components
|
|
58828
59285
|
});
|
|
58829
|
-
|
|
59286
|
+
log50.info(`Updated A2UI components on surface '${params.surfaceId}' (${params.components.length} components)`);
|
|
58830
59287
|
return JSON.stringify({
|
|
58831
59288
|
status: "updated",
|
|
58832
59289
|
surfaceId: params.surfaceId,
|
|
@@ -58836,7 +59293,7 @@ Root component: usar id="root" expl\xEDcito.`,
|
|
|
58836
59293
|
};
|
|
58837
59294
|
}
|
|
58838
59295
|
function createA2UIUpdateDataModelTool(_config) {
|
|
58839
|
-
const
|
|
59296
|
+
const log50 = logger.child("a2ui-data");
|
|
58840
59297
|
return {
|
|
58841
59298
|
name: "a2ui_update_data_model",
|
|
58842
59299
|
description: "Update the data model for an A2UI v0.9 surface. The data model provides dynamic values that components can bind to via paths (e.g. '/user/name').",
|
|
@@ -58873,7 +59330,7 @@ function createA2UIUpdateDataModelTool(_config) {
|
|
|
58873
59330
|
path: params.path,
|
|
58874
59331
|
value: params.value
|
|
58875
59332
|
});
|
|
58876
|
-
|
|
59333
|
+
log50.info(`Updated A2UI data model on surface '${params.surfaceId}' (path: ${params.path ?? "/"})`);
|
|
58877
59334
|
return JSON.stringify({
|
|
58878
59335
|
status: "updated",
|
|
58879
59336
|
surfaceId: params.surfaceId,
|
|
@@ -58883,7 +59340,7 @@ function createA2UIUpdateDataModelTool(_config) {
|
|
|
58883
59340
|
};
|
|
58884
59341
|
}
|
|
58885
59342
|
function createA2UIDeleteSurfaceTool(_config) {
|
|
58886
|
-
const
|
|
59343
|
+
const log50 = logger.child("a2ui-delete");
|
|
58887
59344
|
return {
|
|
58888
59345
|
name: "a2ui_delete_surface",
|
|
58889
59346
|
description: "Delete an A2UI v0.9 surface and remove it from the user's canvas",
|
|
@@ -58910,7 +59367,7 @@ function createA2UIDeleteSurfaceTool(_config) {
|
|
|
58910
59367
|
await canvasManager.sendA2UIMessage(sessionId, "a2ui:deleteSurface", {
|
|
58911
59368
|
surfaceId: params.surfaceId
|
|
58912
59369
|
});
|
|
58913
|
-
|
|
59370
|
+
log50.info(`Deleted A2UI surface '${params.surfaceId}'`);
|
|
58914
59371
|
return JSON.stringify({
|
|
58915
59372
|
status: "deleted",
|
|
58916
59373
|
surfaceId: params.surfaceId
|
|
@@ -58949,13 +59406,13 @@ function createTools6(config2) {
|
|
|
58949
59406
|
createA2UIDeleteSurfaceTool(a2uiConfig)
|
|
58950
59407
|
];
|
|
58951
59408
|
}
|
|
58952
|
-
var
|
|
59409
|
+
var log50, pendingInteractions, canvasRenderTool, canvasAskTool, canvasConfirmTool, canvasShowCardTool, canvasShowProgressTool, canvasShowListTool, canvasClearTool;
|
|
58953
59410
|
var init_canvas = __esm(() => {
|
|
58954
59411
|
init_emitter();
|
|
58955
59412
|
init_logger();
|
|
58956
59413
|
init_canvas_manager();
|
|
58957
59414
|
init_a2ui_tools();
|
|
58958
|
-
|
|
59415
|
+
log50 = logger.child("canvas");
|
|
58959
59416
|
pendingInteractions = new Map;
|
|
58960
59417
|
canvasRenderTool = {
|
|
58961
59418
|
name: "canvas_render",
|
|
@@ -59271,10 +59728,10 @@ var init_canvas = __esm(() => {
|
|
|
59271
59728
|
function createTools7() {
|
|
59272
59729
|
return [voiceTranscribeTool, voiceSpeakTool];
|
|
59273
59730
|
}
|
|
59274
|
-
var
|
|
59731
|
+
var log51, voiceTranscribeTool, voiceSpeakTool;
|
|
59275
59732
|
var init_voice = __esm(() => {
|
|
59276
59733
|
init_logger();
|
|
59277
|
-
|
|
59734
|
+
log51 = logger.child("voice");
|
|
59278
59735
|
voiceTranscribeTool = {
|
|
59279
59736
|
name: "voice_transcribe",
|
|
59280
59737
|
description: "Transcribe audio input to text. Spanish: transcribir audio, voz a texto, reconocimiento de voz",
|
|
@@ -59295,7 +59752,7 @@ var init_voice = __esm(() => {
|
|
|
59295
59752
|
execute: async (params) => {
|
|
59296
59753
|
const audio = params.audio;
|
|
59297
59754
|
const language = params.language ?? "auto";
|
|
59298
|
-
|
|
59755
|
+
log51.info(`Transcribing audio: ${audio.substring(0, 50)}...`);
|
|
59299
59756
|
try {
|
|
59300
59757
|
return {
|
|
59301
59758
|
ok: true,
|
|
@@ -59337,7 +59794,7 @@ var init_voice = __esm(() => {
|
|
|
59337
59794
|
const text = params.text;
|
|
59338
59795
|
const voiceId = params.voice_id ?? "default";
|
|
59339
59796
|
const language = params.language ?? "es";
|
|
59340
|
-
|
|
59797
|
+
log51.info(`Synthesizing speech: ${text.substring(0, 50)}...`);
|
|
59341
59798
|
try {
|
|
59342
59799
|
return {
|
|
59343
59800
|
ok: true,
|
|
@@ -59374,11 +59831,11 @@ function buildFtsMatch(words) {
|
|
|
59374
59831
|
function createTools8() {
|
|
59375
59832
|
return [searchKnowledgeTool, notifyTool, saveNoteTool, reportProgressTool];
|
|
59376
59833
|
}
|
|
59377
|
-
var
|
|
59834
|
+
var log52, ES_EN_DICT, searchKnowledgeTool, notifyTool, saveNoteTool, reportProgressTool;
|
|
59378
59835
|
var init_core3 = __esm(() => {
|
|
59379
59836
|
init_sqlite();
|
|
59380
59837
|
init_logger();
|
|
59381
|
-
|
|
59838
|
+
log52 = logger.child("core");
|
|
59382
59839
|
ES_EN_DICT = {
|
|
59383
59840
|
buscar: ["search", "find", "list", "get", "query"],
|
|
59384
59841
|
listar: ["list", "get", "fetch", "retrieve"],
|
|
@@ -59569,7 +60026,7 @@ var init_core3 = __esm(() => {
|
|
|
59569
60026
|
}
|
|
59570
60027
|
};
|
|
59571
60028
|
if (!query2) {
|
|
59572
|
-
|
|
60029
|
+
log52.info(`[search_knowledge] Empty query \u2014 returning empty results`);
|
|
59573
60030
|
return { query: query2, type, tools: [], skills: [], playbook: [], toolsmcp: [] };
|
|
59574
60031
|
}
|
|
59575
60032
|
const escapedQuery = query2.replace(/'/g, "''");
|
|
@@ -59628,7 +60085,7 @@ var init_core3 = __esm(() => {
|
|
|
59628
60085
|
if (englishQuery.length > 0) {
|
|
59629
60086
|
const enWords = englishQuery.split(/\s+/).filter((w2) => w2.length > 0);
|
|
59630
60087
|
const enMatch = buildFtsMatch(enWords);
|
|
59631
|
-
|
|
60088
|
+
log52.info(`[search_knowledge] Bilingual fallback: "${normalizedQuery}" \u2192 "${englishQuery}" (first pass: ${totalFirst} results)`);
|
|
59632
60089
|
const existingIds = new Set([
|
|
59633
60090
|
...result.tools.map((t) => t.name),
|
|
59634
60091
|
...result.skills.map((s2) => s2.id),
|
|
@@ -59726,7 +60183,7 @@ var init_core3 = __esm(() => {
|
|
|
59726
60183
|
const message = params.message;
|
|
59727
60184
|
const channel = config2?.configurable?.channel ?? "webchat";
|
|
59728
60185
|
const userId = config2?.configurable?.user_id ?? "";
|
|
59729
|
-
|
|
60186
|
+
log52.info(`[notify] Sending to ${channel}/${userId}: ${message.substring(0, 80)}`);
|
|
59730
60187
|
const result = await sendToUserChannel2(channel, userId, message);
|
|
59731
60188
|
if (!result.ok)
|
|
59732
60189
|
throw new Error(`Channel send failed: ${result.error}`);
|
|
@@ -59801,7 +60258,7 @@ var init_core3 = __esm(() => {
|
|
|
59801
60258
|
const taskId = params.task_id ?? null;
|
|
59802
60259
|
const channel = config2?.configurable?.channel ?? "webchat";
|
|
59803
60260
|
const userId = config2?.configurable?.user_id ?? "";
|
|
59804
|
-
|
|
60261
|
+
log52.info(`[report_progress] ${progress}% \u2014 ${message}`);
|
|
59805
60262
|
if (taskId) {
|
|
59806
60263
|
const db = getDb();
|
|
59807
60264
|
db.query(`UPDATE tasks SET progress = ?, updated_at = unixepoch() WHERE id = ?`).run(progress, taskId);
|
|
@@ -117207,10 +117664,10 @@ var init_pdf2 = __esm(() => {
|
|
|
117207
117664
|
// packages/core/src/tools/office/office-leer-pdf.ts
|
|
117208
117665
|
import * as fs11 from "fs";
|
|
117209
117666
|
import * as path12 from "path";
|
|
117210
|
-
var
|
|
117667
|
+
var log53, officeLeerPdfTool;
|
|
117211
117668
|
var init_office_leer_pdf = __esm(() => {
|
|
117212
117669
|
init_logger();
|
|
117213
|
-
|
|
117670
|
+
log53 = logger.child("office-leer-pdf");
|
|
117214
117671
|
officeLeerPdfTool = {
|
|
117215
117672
|
name: "office_leer_pdf",
|
|
117216
117673
|
description: "Leer contenido de un archivo PDF y retornar texto plano con metadata. Spanish: leer pdf, abrir pdf, extraer texto de pdf, pdf a texto",
|
|
@@ -117236,7 +117693,7 @@ var init_office_leer_pdf = __esm(() => {
|
|
|
117236
117693
|
const ruta = params.ruta;
|
|
117237
117694
|
const paginaInicio = Math.max(1, params.pagina_inicio ?? 1);
|
|
117238
117695
|
const paginaFin = params.pagina_fin;
|
|
117239
|
-
|
|
117696
|
+
log53.debug(`Leyendo PDF: ${ruta}`);
|
|
117240
117697
|
try {
|
|
117241
117698
|
const rutaAbsoluta = path12.resolve(ruta);
|
|
117242
117699
|
if (!fs11.existsSync(rutaAbsoluta)) {
|
|
@@ -117268,7 +117725,7 @@ var init_office_leer_pdf = __esm(() => {
|
|
|
117268
117725
|
const textoCompleto = textosPorPagina.map((p2) => p2.texto).join(`
|
|
117269
117726
|
|
|
117270
117727
|
`);
|
|
117271
|
-
|
|
117728
|
+
log53.info(`PDF le\xEDdo: ${totalPaginas} p\xE1ginas, ${textoCompleto.length} caracteres`);
|
|
117272
117729
|
return {
|
|
117273
117730
|
ok: true,
|
|
117274
117731
|
ruta: rutaAbsoluta,
|
|
@@ -117279,7 +117736,7 @@ var init_office_leer_pdf = __esm(() => {
|
|
|
117279
117736
|
paginas: textosPorPagina
|
|
117280
117737
|
};
|
|
117281
117738
|
} catch (error4) {
|
|
117282
|
-
|
|
117739
|
+
log53.error(`Error leyendo PDF: ${error4.message}`);
|
|
117283
117740
|
return {
|
|
117284
117741
|
ok: false,
|
|
117285
117742
|
error: `No se pudo leer el PDF: ${error4.message}`
|
|
@@ -138038,10 +138495,10 @@ var init_es2 = __esm(() => {
|
|
|
138038
138495
|
// packages/core/src/tools/office/office-escribir-pdf.ts
|
|
138039
138496
|
import * as path13 from "path";
|
|
138040
138497
|
import * as fs12 from "fs";
|
|
138041
|
-
var
|
|
138498
|
+
var log54, officeEscribirPdfTool;
|
|
138042
138499
|
var init_office_escribir_pdf = __esm(() => {
|
|
138043
138500
|
init_logger();
|
|
138044
|
-
|
|
138501
|
+
log54 = logger.child("office-escribir-pdf");
|
|
138045
138502
|
officeEscribirPdfTool = {
|
|
138046
138503
|
name: "office_escribir_pdf",
|
|
138047
138504
|
description: "Generar un archivo PDF desde texto con configuraci\xF3n de m\xE1rgenes y tama\xF1o de p\xE1gina. Spanish: crear pdf, generar pdf, escribir pdf, exportar a pdf",
|
|
@@ -138083,7 +138540,7 @@ var init_office_escribir_pdf = __esm(() => {
|
|
|
138083
138540
|
const tama_oPagina = params.tama\u{f1}o_pagina ?? "A4";
|
|
138084
138541
|
const margen = params.margen ?? 50;
|
|
138085
138542
|
const tama_oFuente = params.tama\u{f1}o_fuente ?? 12;
|
|
138086
|
-
|
|
138543
|
+
log54.debug(`Generando PDF: ${ruta}`);
|
|
138087
138544
|
try {
|
|
138088
138545
|
const { PDFDocument: PDFDocument2, StandardFonts: StandardFonts3, rgb: rgb2, PageSizes: PageSizes2 } = await Promise.resolve().then(() => (init_es2(), exports_es));
|
|
138089
138546
|
const pdfDoc = await PDFDocument2.create();
|
|
@@ -138157,7 +138614,7 @@ var init_office_escribir_pdf = __esm(() => {
|
|
|
138157
138614
|
}
|
|
138158
138615
|
const pdfBytes = await pdfDoc.save();
|
|
138159
138616
|
fs12.writeFileSync(rutaAbsoluta, pdfBytes);
|
|
138160
|
-
|
|
138617
|
+
log54.info(`PDF generado: ${rutaAbsoluta} (${pdfDoc.getPageCount()} p\xE1ginas)`);
|
|
138161
138618
|
return {
|
|
138162
138619
|
ok: true,
|
|
138163
138620
|
ruta: rutaAbsoluta,
|
|
@@ -138165,7 +138622,7 @@ var init_office_escribir_pdf = __esm(() => {
|
|
|
138165
138622
|
bytesEscritos: pdfBytes.length
|
|
138166
138623
|
};
|
|
138167
138624
|
} catch (error5) {
|
|
138168
|
-
|
|
138625
|
+
log54.error(`Error generando PDF: ${error5.message}`);
|
|
138169
138626
|
return {
|
|
138170
138627
|
ok: false,
|
|
138171
138628
|
error: `No se pudo generar el PDF: ${error5.message}`
|
|
@@ -162040,10 +162497,10 @@ var require_lib6 = __commonJS((exports) => {
|
|
|
162040
162497
|
// packages/core/src/tools/office/office-leer-docx.ts
|
|
162041
162498
|
import * as fs13 from "fs";
|
|
162042
162499
|
import * as path14 from "path";
|
|
162043
|
-
var
|
|
162500
|
+
var log55, officeLeerDocxTool;
|
|
162044
162501
|
var init_office_leer_docx = __esm(() => {
|
|
162045
162502
|
init_logger();
|
|
162046
|
-
|
|
162503
|
+
log55 = logger.child("office-leer-docx");
|
|
162047
162504
|
officeLeerDocxTool = {
|
|
162048
162505
|
name: "office_leer_docx",
|
|
162049
162506
|
description: "Leer un archivo Word (.docx) y retornar el contenido de texto preservando p\xE1rrafos y tablas. Spanish: leer word, abrir docx, extraer texto de word, contenido word",
|
|
@@ -162064,7 +162521,7 @@ var init_office_leer_docx = __esm(() => {
|
|
|
162064
162521
|
execute: async (params) => {
|
|
162065
162522
|
const ruta = params.ruta;
|
|
162066
162523
|
const incluirTablas = params.incluir_tablas ?? true;
|
|
162067
|
-
|
|
162524
|
+
log55.debug(`Leyendo DOCX: ${ruta}`);
|
|
162068
162525
|
try {
|
|
162069
162526
|
const rutaAbsoluta = path14.resolve(ruta);
|
|
162070
162527
|
if (!fs13.existsSync(rutaAbsoluta)) {
|
|
@@ -162089,7 +162546,7 @@ ${textoCeldas.join(" | ")}`;
|
|
|
162089
162546
|
}
|
|
162090
162547
|
}
|
|
162091
162548
|
const advertencias = resultadoTexto.messages.filter((m2) => m2.type === "warning").map((m2) => m2.message);
|
|
162092
|
-
|
|
162549
|
+
log55.info(`DOCX le\xEDdo: ${resultadoTexto.value.length} caracteres`);
|
|
162093
162550
|
return {
|
|
162094
162551
|
ok: true,
|
|
162095
162552
|
ruta: rutaAbsoluta,
|
|
@@ -162098,7 +162555,7 @@ ${textoCeldas.join(" | ")}`;
|
|
|
162098
162555
|
advertencias: advertencias.length > 0 ? advertencias : undefined
|
|
162099
162556
|
};
|
|
162100
162557
|
} catch (error5) {
|
|
162101
|
-
|
|
162558
|
+
log55.error(`Error leyendo DOCX: ${error5.message}`);
|
|
162102
162559
|
return {
|
|
162103
162560
|
ok: false,
|
|
162104
162561
|
error: `No se pudo leer el archivo DOCX: ${error5.message}`
|
|
@@ -183937,10 +184394,10 @@ var init_dist3 = __esm(() => {
|
|
|
183937
184394
|
// packages/core/src/tools/office/office-escribir-docx.ts
|
|
183938
184395
|
import * as path15 from "path";
|
|
183939
184396
|
import * as fs14 from "fs";
|
|
183940
|
-
var
|
|
184397
|
+
var log56, officeEscribirDocxTool;
|
|
183941
184398
|
var init_office_escribir_docx = __esm(() => {
|
|
183942
184399
|
init_logger();
|
|
183943
|
-
|
|
184400
|
+
log56 = logger.child("office-escribir-docx");
|
|
183944
184401
|
officeEscribirDocxTool = {
|
|
183945
184402
|
name: "office_escribir_docx",
|
|
183946
184403
|
description: "Generar un archivo Word (.docx) con p\xE1rrafos, t\xEDtulos y tablas. Spanish: crear word, generar docx, escribir documento word, exportar a docx",
|
|
@@ -183987,7 +184444,7 @@ var init_office_escribir_docx = __esm(() => {
|
|
|
183987
184444
|
const titulo = params.titulo;
|
|
183988
184445
|
const parrafosInput = params.parrafos ?? [];
|
|
183989
184446
|
const tablasInput = params.tablas ?? [];
|
|
183990
|
-
|
|
184447
|
+
log56.debug(`Generando DOCX: ${ruta}`);
|
|
183991
184448
|
try {
|
|
183992
184449
|
const {
|
|
183993
184450
|
Document: Document2,
|
|
@@ -184067,7 +184524,7 @@ var init_office_escribir_docx = __esm(() => {
|
|
|
184067
184524
|
}
|
|
184068
184525
|
const buffer2 = await Packer2.toBuffer(doc2);
|
|
184069
184526
|
fs14.writeFileSync(rutaAbsoluta, buffer2);
|
|
184070
|
-
|
|
184527
|
+
log56.info(`DOCX generado: ${rutaAbsoluta} (${buffer2.length} bytes)`);
|
|
184071
184528
|
return {
|
|
184072
184529
|
ok: true,
|
|
184073
184530
|
ruta: rutaAbsoluta,
|
|
@@ -184076,7 +184533,7 @@ var init_office_escribir_docx = __esm(() => {
|
|
|
184076
184533
|
tablas: tablasInput.length
|
|
184077
184534
|
};
|
|
184078
184535
|
} catch (error5) {
|
|
184079
|
-
|
|
184536
|
+
log56.error(`Error generando DOCX: ${error5.message}`);
|
|
184080
184537
|
return {
|
|
184081
184538
|
ok: false,
|
|
184082
184539
|
error: `No se pudo generar el archivo DOCX: ${error5.message}`
|
|
@@ -211988,10 +212445,10 @@ var init_xlsx = __esm(() => {
|
|
|
211988
212445
|
// packages/core/src/tools/office/office-leer-xlsx.ts
|
|
211989
212446
|
import * as fs15 from "fs";
|
|
211990
212447
|
import * as path16 from "path";
|
|
211991
|
-
var
|
|
212448
|
+
var log57, officeLeerXlsxTool;
|
|
211992
212449
|
var init_office_leer_xlsx = __esm(() => {
|
|
211993
212450
|
init_logger();
|
|
211994
|
-
|
|
212451
|
+
log57 = logger.child("office-leer-xlsx");
|
|
211995
212452
|
officeLeerXlsxTool = {
|
|
211996
212453
|
name: "office_leer_xlsx",
|
|
211997
212454
|
description: "Leer un archivo Excel (.xlsx) y retornar las hojas con sus datos como objetos JSON. Spanish: leer excel, abrir xlsx, extraer datos de excel, hojas excel",
|
|
@@ -212022,7 +212479,7 @@ var init_office_leer_xlsx = __esm(() => {
|
|
|
212022
212479
|
const hojaFiltro = params.hoja;
|
|
212023
212480
|
const incluirEncabezados = params.incluir_encabezados ?? true;
|
|
212024
212481
|
const rango = params.rango;
|
|
212025
|
-
|
|
212482
|
+
log57.debug(`Leyendo XLSX: ${ruta}`);
|
|
212026
212483
|
try {
|
|
212027
212484
|
const rutaAbsoluta = path16.resolve(ruta);
|
|
212028
212485
|
if (!fs15.existsSync(rutaAbsoluta)) {
|
|
@@ -212036,7 +212493,7 @@ var init_office_leer_xlsx = __esm(() => {
|
|
|
212036
212493
|
for (const nombreHoja of nombresHojas) {
|
|
212037
212494
|
const hoja = workbook.Sheets[nombreHoja];
|
|
212038
212495
|
if (!hoja) {
|
|
212039
|
-
|
|
212496
|
+
log57.warn(`Hoja '${nombreHoja}' no encontrada en el archivo`);
|
|
212040
212497
|
continue;
|
|
212041
212498
|
}
|
|
212042
212499
|
const opciones = {
|
|
@@ -212060,7 +212517,7 @@ var init_office_leer_xlsx = __esm(() => {
|
|
|
212060
212517
|
}
|
|
212061
212518
|
}
|
|
212062
212519
|
const totalFilas = Object.values(hojas).reduce((acc, filas) => acc + filas.length, 0);
|
|
212063
|
-
|
|
212520
|
+
log57.info(`XLSX le\xEDdo: ${nombresHojas.length} hojas, ${totalFilas} filas totales`);
|
|
212064
212521
|
return {
|
|
212065
212522
|
ok: true,
|
|
212066
212523
|
ruta: rutaAbsoluta,
|
|
@@ -212069,7 +212526,7 @@ var init_office_leer_xlsx = __esm(() => {
|
|
|
212069
212526
|
totalFilas
|
|
212070
212527
|
};
|
|
212071
212528
|
} catch (error5) {
|
|
212072
|
-
|
|
212529
|
+
log57.error(`Error leyendo XLSX: ${error5.message}`);
|
|
212073
212530
|
return {
|
|
212074
212531
|
ok: false,
|
|
212075
212532
|
error: `No se pudo leer el archivo Excel: ${error5.message}`
|
|
@@ -212082,10 +212539,10 @@ var init_office_leer_xlsx = __esm(() => {
|
|
|
212082
212539
|
// packages/core/src/tools/office/office-escribir-xlsx.ts
|
|
212083
212540
|
import * as path17 from "path";
|
|
212084
212541
|
import * as fs16 from "fs";
|
|
212085
|
-
var
|
|
212542
|
+
var log58, officeEscribirXlsxTool;
|
|
212086
212543
|
var init_office_escribir_xlsx = __esm(() => {
|
|
212087
212544
|
init_logger();
|
|
212088
|
-
|
|
212545
|
+
log58 = logger.child("office-escribir-xlsx");
|
|
212089
212546
|
officeEscribirXlsxTool = {
|
|
212090
212547
|
name: "office_escribir_xlsx",
|
|
212091
212548
|
description: "Generar un archivo Excel (.xlsx) desde un objeto JSON con hojas, filas y columnas. Spanish: crear excel, generar xlsx, escribir excel, exportar a xlsx",
|
|
@@ -212114,7 +212571,7 @@ var init_office_escribir_xlsx = __esm(() => {
|
|
|
212114
212571
|
execute: async (params) => {
|
|
212115
212572
|
const ruta = params.ruta;
|
|
212116
212573
|
const hojasInput = params.hojas;
|
|
212117
|
-
|
|
212574
|
+
log58.debug(`Generando XLSX: ${ruta}`);
|
|
212118
212575
|
try {
|
|
212119
212576
|
const XLSX2 = await Promise.resolve().then(() => (init_xlsx(), exports_xlsx));
|
|
212120
212577
|
const workbook = XLSX2.utils.book_new();
|
|
@@ -212135,7 +212592,7 @@ var init_office_escribir_xlsx = __esm(() => {
|
|
|
212135
212592
|
const buffer2 = XLSX2.write(workbook, { type: "buffer", bookType: "xlsx" });
|
|
212136
212593
|
fs16.writeFileSync(rutaAbsoluta, buffer2);
|
|
212137
212594
|
const totalFilas = hojasInput.reduce((acc, h) => acc + h.datos.length, 0);
|
|
212138
|
-
|
|
212595
|
+
log58.info(`XLSX generado: ${rutaAbsoluta} (${hojasInput.length} hojas, ${totalFilas} filas)`);
|
|
212139
212596
|
return {
|
|
212140
212597
|
ok: true,
|
|
212141
212598
|
ruta: rutaAbsoluta,
|
|
@@ -212145,7 +212602,7 @@ var init_office_escribir_xlsx = __esm(() => {
|
|
|
212145
212602
|
bytesEscritos: buffer2.length
|
|
212146
212603
|
};
|
|
212147
212604
|
} catch (error5) {
|
|
212148
|
-
|
|
212605
|
+
log58.error(`Error generando XLSX: ${error5.message}`);
|
|
212149
212606
|
return {
|
|
212150
212607
|
ok: false,
|
|
212151
212608
|
error: `No se pudo generar el archivo Excel: ${error5.message}`
|
|
@@ -212158,10 +212615,10 @@ var init_office_escribir_xlsx = __esm(() => {
|
|
|
212158
212615
|
// packages/core/src/tools/office/office-leer-pptx.ts
|
|
212159
212616
|
import * as fs17 from "fs";
|
|
212160
212617
|
import * as path18 from "path";
|
|
212161
|
-
var
|
|
212618
|
+
var log59, officeLeerPptxTool;
|
|
212162
212619
|
var init_office_leer_pptx = __esm(() => {
|
|
212163
212620
|
init_logger();
|
|
212164
|
-
|
|
212621
|
+
log59 = logger.child("office-leer-pptx");
|
|
212165
212622
|
officeLeerPptxTool = {
|
|
212166
212623
|
name: "office_leer_pptx",
|
|
212167
212624
|
description: "Leer un archivo PowerPoint (.pptx) y retornar el texto de cada diapositiva como array estructurado. Spanish: leer powerpoint, abrir pptx, extraer texto de presentacion, contenido slides",
|
|
@@ -212182,7 +212639,7 @@ var init_office_leer_pptx = __esm(() => {
|
|
|
212182
212639
|
execute: async (params) => {
|
|
212183
212640
|
const ruta = params.ruta;
|
|
212184
212641
|
const soloSlide = params.solo_diapositiva;
|
|
212185
|
-
|
|
212642
|
+
log59.debug(`Leyendo PPTX: ${ruta}`);
|
|
212186
212643
|
try {
|
|
212187
212644
|
const rutaAbsoluta = path18.resolve(ruta);
|
|
212188
212645
|
if (!fs17.existsSync(rutaAbsoluta)) {
|
|
@@ -212229,7 +212686,7 @@ var init_office_leer_pptx = __esm(() => {
|
|
|
212229
212686
|
fragmentos
|
|
212230
212687
|
});
|
|
212231
212688
|
}
|
|
212232
|
-
|
|
212689
|
+
log59.info(`PPTX le\xEDdo: ${archivosSlides.length} slides totales, ${diapositivas.length} le\xEDdas`);
|
|
212233
212690
|
return {
|
|
212234
212691
|
ok: true,
|
|
212235
212692
|
ruta: rutaAbsoluta,
|
|
@@ -212237,7 +212694,7 @@ var init_office_leer_pptx = __esm(() => {
|
|
|
212237
212694
|
diapositivas
|
|
212238
212695
|
};
|
|
212239
212696
|
} catch (error5) {
|
|
212240
|
-
|
|
212697
|
+
log59.error(`Error leyendo PPTX: ${error5.message}`);
|
|
212241
212698
|
return {
|
|
212242
212699
|
ok: false,
|
|
212243
212700
|
error: `No se pudo leer el archivo PowerPoint: ${error5.message}`
|
|
@@ -217466,10 +217923,10 @@ var init_pptxgen_es = __esm(() => {
|
|
|
217466
217923
|
// packages/core/src/tools/office/office-escribir-pptx.ts
|
|
217467
217924
|
import * as path19 from "path";
|
|
217468
217925
|
import * as fs18 from "fs";
|
|
217469
|
-
var
|
|
217926
|
+
var log60, officeEscribirPptxTool;
|
|
217470
217927
|
var init_office_escribir_pptx = __esm(() => {
|
|
217471
217928
|
init_logger();
|
|
217472
|
-
|
|
217929
|
+
log60 = logger.child("office-escribir-pptx");
|
|
217473
217930
|
officeEscribirPptxTool = {
|
|
217474
217931
|
name: "office_escribir_pptx",
|
|
217475
217932
|
description: "Generar un archivo PowerPoint (.pptx) desde un array de diapositivas con t\xEDtulo y contenido. Spanish: crear powerpoint, generar pptx, escribir presentacion, exportar a pptx",
|
|
@@ -217504,7 +217961,7 @@ var init_office_escribir_pptx = __esm(() => {
|
|
|
217504
217961
|
const ruta = params.ruta;
|
|
217505
217962
|
const tituloPresentacion = params.titulo_presentacion;
|
|
217506
217963
|
const diapositivasInput = params.diapositivas;
|
|
217507
|
-
|
|
217964
|
+
log60.debug(`Generando PPTX: ${ruta}`);
|
|
217508
217965
|
try {
|
|
217509
217966
|
const pptxgen = (await Promise.resolve().then(() => (init_pptxgen_es(), exports_pptxgen_es))).default;
|
|
217510
217967
|
const pres = new pptxgen;
|
|
@@ -217578,7 +218035,7 @@ var init_office_escribir_pptx = __esm(() => {
|
|
|
217578
218035
|
}
|
|
217579
218036
|
await pres.writeFile({ fileName: rutaAbsoluta });
|
|
217580
218037
|
const stats = fs18.statSync(rutaAbsoluta);
|
|
217581
|
-
|
|
218038
|
+
log60.info(`PPTX generado: ${rutaAbsoluta} (${diapositivasInput.length} diapositivas)`);
|
|
217582
218039
|
return {
|
|
217583
218040
|
ok: true,
|
|
217584
218041
|
ruta: rutaAbsoluta,
|
|
@@ -217586,7 +218043,7 @@ var init_office_escribir_pptx = __esm(() => {
|
|
|
217586
218043
|
bytesEscritos: stats.size
|
|
217587
218044
|
};
|
|
217588
218045
|
} catch (error5) {
|
|
217589
|
-
|
|
218046
|
+
log60.error(`Error generando PPTX: ${error5.message}`);
|
|
217590
218047
|
return {
|
|
217591
218048
|
ok: false,
|
|
217592
218049
|
error: `No se pudo generar el archivo PowerPoint: ${error5.message}`
|
|
@@ -217675,7 +218132,7 @@ class VoiceService {
|
|
|
217675
218132
|
} else if (isOpenAi) {
|
|
217676
218133
|
return this.transcribeWithOpenAIWhisper(audio);
|
|
217677
218134
|
}
|
|
217678
|
-
|
|
218135
|
+
log61.warn(`Unknown STT provider ${modelId}, defaulting to Groq Whisper`);
|
|
217679
218136
|
return this.transcribeWithGroq(audio, "whisper-large-v3-turbo");
|
|
217680
218137
|
}
|
|
217681
218138
|
async getProviderApiKey(providerId) {
|
|
@@ -217777,7 +218234,7 @@ class VoiceService {
|
|
|
217777
218234
|
} else if (isQwen) {
|
|
217778
218235
|
return this.speakWithQwen(text2, modelId, voiceId);
|
|
217779
218236
|
}
|
|
217780
|
-
|
|
218237
|
+
log61.warn(`Unknown TTS provider ${modelId}, defaulting to ElevenLabs Flash`);
|
|
217781
218238
|
return this.speakWithElevenLabs(text2, "eleven_flash_v2_5", voiceId);
|
|
217782
218239
|
}
|
|
217783
218240
|
async speakWithPiper(text2, voiceId) {
|
|
@@ -218117,12 +218574,12 @@ class VoiceService {
|
|
|
218117
218574
|
throw new Error("WebChat audio missing base64 or buffer");
|
|
218118
218575
|
}
|
|
218119
218576
|
}
|
|
218120
|
-
var
|
|
218577
|
+
var log61, voiceService;
|
|
218121
218578
|
var init_voice2 = __esm(() => {
|
|
218122
218579
|
init_sqlite();
|
|
218123
218580
|
init_crypto();
|
|
218124
218581
|
init_logger();
|
|
218125
|
-
|
|
218582
|
+
log61 = logger.child("voice");
|
|
218126
218583
|
voiceService = VoiceService.getInstance();
|
|
218127
218584
|
});
|
|
218128
218585
|
|
|
@@ -218135,12 +218592,12 @@ function createTools10() {
|
|
|
218135
218592
|
meetingReportTool
|
|
218136
218593
|
];
|
|
218137
218594
|
}
|
|
218138
|
-
var
|
|
218595
|
+
var log62, meetingStartTool, meetingAddSegmentTool, meetingStopTool, meetingReportTool;
|
|
218139
218596
|
var init_meeting = __esm(() => {
|
|
218140
218597
|
init_sqlite();
|
|
218141
218598
|
init_voice2();
|
|
218142
218599
|
init_logger();
|
|
218143
|
-
|
|
218600
|
+
log62 = logger.child("meeting");
|
|
218144
218601
|
meetingStartTool = {
|
|
218145
218602
|
name: "meeting_start",
|
|
218146
218603
|
description: "Inicia una sesi\xF3n de transcripci\xF3n de reuni\xF3n en tiempo real. | Start a real-time meeting transcription session.",
|
|
@@ -218166,7 +218623,7 @@ var init_meeting = __esm(() => {
|
|
|
218166
218623
|
const result = db.query(`INSERT INTO meeting_sessions (title, stt_model)
|
|
218167
218624
|
VALUES (?, ?)
|
|
218168
218625
|
RETURNING id, title, status, stt_model, started_at`).get(title, sttModel);
|
|
218169
|
-
|
|
218626
|
+
log62.info(`Meeting session started: ${result.id} \u2014 "${title}"`);
|
|
218170
218627
|
return {
|
|
218171
218628
|
ok: true,
|
|
218172
218629
|
session_id: result.id,
|
|
@@ -218178,7 +218635,7 @@ T\xEDtulo: "${title}"
|
|
|
218178
218635
|
Modelo STT: ${sttModel}`
|
|
218179
218636
|
};
|
|
218180
218637
|
} catch (error5) {
|
|
218181
|
-
|
|
218638
|
+
log62.error(`meeting_start error: ${error5.message}`);
|
|
218182
218639
|
return { ok: false, error: `Error al iniciar la sesi\xF3n: ${error5.message}` };
|
|
218183
218640
|
}
|
|
218184
218641
|
}
|
|
@@ -218243,7 +218700,7 @@ Modelo STT: ${sttModel}`
|
|
|
218243
218700
|
const seq = seqResult.next_seq;
|
|
218244
218701
|
db.query(`INSERT INTO meeting_segments (session_id, seq, speaker, text, duration_ms)
|
|
218245
218702
|
VALUES (?, ?, ?, ?, NULL)`).run(sessionId, seq, speaker, transcription);
|
|
218246
|
-
|
|
218703
|
+
log62.info(`Segment ${seq} added to session ${sessionId}: "${transcription.substring(0, 60)}..."`);
|
|
218247
218704
|
return {
|
|
218248
218705
|
ok: true,
|
|
218249
218706
|
seq,
|
|
@@ -218252,7 +218709,7 @@ Modelo STT: ${sttModel}`
|
|
|
218252
218709
|
message: speaker ? `[${speaker}]: ${transcription}` : transcription
|
|
218253
218710
|
};
|
|
218254
218711
|
} catch (error5) {
|
|
218255
|
-
|
|
218712
|
+
log62.error(`meeting_add_segment error: ${error5.message}`);
|
|
218256
218713
|
return {
|
|
218257
218714
|
ok: false,
|
|
218258
218715
|
error: `Error al agregar segmento: ${error5.message}`
|
|
@@ -218290,7 +218747,7 @@ Modelo STT: ${sttModel}`
|
|
|
218290
218747
|
}
|
|
218291
218748
|
db.query(`UPDATE meeting_sessions SET status = 'stopped', stopped_at = unixepoch() WHERE id = ?`).run(sessionId);
|
|
218292
218749
|
const countResult = db.query(`SELECT COUNT(*) as count FROM meeting_segments WHERE session_id = ?`).get(sessionId);
|
|
218293
|
-
|
|
218750
|
+
log62.info(`Meeting session stopped: ${sessionId} \u2014 ${countResult.count} segments`);
|
|
218294
218751
|
return {
|
|
218295
218752
|
ok: true,
|
|
218296
218753
|
session_id: sessionId,
|
|
@@ -218302,7 +218759,7 @@ ${countResult.count} segmentos transcritos.
|
|
|
218302
218759
|
Puedes pedir el reporte con: "Genera el reporte de la reuni\xF3n ${sessionId}"`
|
|
218303
218760
|
};
|
|
218304
218761
|
} catch (error5) {
|
|
218305
|
-
|
|
218762
|
+
log62.error(`meeting_stop error: ${error5.message}`);
|
|
218306
218763
|
return { ok: false, error: `Error al detener la sesi\xF3n: ${error5.message}` };
|
|
218307
218764
|
}
|
|
218308
218765
|
}
|
|
@@ -218378,7 +218835,7 @@ Puedes pedir el reporte con: "Genera el reporte de la reuni\xF3n ${sessionId}"`
|
|
|
218378
218835
|
Luego llama a office_escribir_docx para guardar el reporte como documento Word.`
|
|
218379
218836
|
};
|
|
218380
218837
|
} catch (error5) {
|
|
218381
|
-
|
|
218838
|
+
log62.error(`meeting_report error: ${error5.message}`);
|
|
218382
218839
|
return {
|
|
218383
218840
|
ok: false,
|
|
218384
218841
|
error: `Error al obtener el reporte: ${error5.message}`
|
|
@@ -218389,10 +218846,10 @@ Luego llama a office_escribir_docx para guardar el reporte como documento Word.`
|
|
|
218389
218846
|
});
|
|
218390
218847
|
|
|
218391
218848
|
// packages/core/src/tools/api/api-request.ts
|
|
218392
|
-
var
|
|
218849
|
+
var log63, ALLOWED_METHODS, apiRequestTool;
|
|
218393
218850
|
var init_api_request = __esm(() => {
|
|
218394
218851
|
init_logger();
|
|
218395
|
-
|
|
218852
|
+
log63 = logger.child("api-request");
|
|
218396
218853
|
ALLOWED_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
|
|
218397
218854
|
apiRequestTool = {
|
|
218398
218855
|
name: "api_request",
|
|
@@ -218458,7 +218915,7 @@ var init_api_request = __esm(() => {
|
|
|
218458
218915
|
}
|
|
218459
218916
|
url = urlObj.toString();
|
|
218460
218917
|
}
|
|
218461
|
-
|
|
218918
|
+
log63.info(`[api_request] ${method} ${url}`);
|
|
218462
218919
|
const fetchOptions = {
|
|
218463
218920
|
method,
|
|
218464
218921
|
headers: {
|
|
@@ -218504,7 +218961,7 @@ var init_api_request = __esm(() => {
|
|
|
218504
218961
|
response.headers.forEach((value, key) => {
|
|
218505
218962
|
responseHeaders[key] = value;
|
|
218506
218963
|
});
|
|
218507
|
-
|
|
218964
|
+
log63.info(`[api_request] ${method} ${url} \u2192 ${response.status} ${response.statusText}`);
|
|
218508
218965
|
return {
|
|
218509
218966
|
ok: response.ok,
|
|
218510
218967
|
status: response.status,
|
|
@@ -218516,7 +218973,7 @@ var init_api_request = __esm(() => {
|
|
|
218516
218973
|
};
|
|
218517
218974
|
} catch (error5) {
|
|
218518
218975
|
const msg = error5.message;
|
|
218519
|
-
|
|
218976
|
+
log63.error(`[api_request] ${method} ${url} failed: ${msg}`);
|
|
218520
218977
|
return {
|
|
218521
218978
|
ok: false,
|
|
218522
218979
|
error: `HTTP request failed: ${msg}`,
|