@xopcai/xopc 0.0.222 → 0.0.224
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-NItGQmvR.js → activity-store--GBciH10.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DsR_2U9-.js → agent-avatar-dicebear-K7V4XXt7.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BsxTpXyq.js +68 -0
- package/dist/gateway/static/root/assets/{api-53ZXsuyr.js → api-HoIz_ija.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BCzVX09V.js → app-management-settings-panel-xQCmkAHh.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DgSpwqQI.js → appearance-settings-BRoeA4kU.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BXgpBA8w.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D8o8CP9Y.js → archive-plugin-CteCVsBP.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BQHcAR6J.js → attachment-load-D7xNA2jB.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CswK3HFb.js → automations-page-BD1vK7r5.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-wrgf-z7D.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BlpyTJ1b.js → binary-plugins-C3DaJa0W.js} +1 -1
- package/dist/gateway/static/root/assets/block-editor-lTkcHTve.js +184 -0
- package/dist/gateway/static/root/assets/browser-settings-page-zhzNkeVG.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bi6RSSpD.js → browser-workflow-inputs-1UZ0vnIy.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CZNOOQY4.js → browser-workflows-page-BHuJOF4M.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DuCmg2Ej.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-pC2fno7r.js → capability-presets-api-yNqTIuyd.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DjiP3mQQ.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-B5Szgu_z.js → channel-recipient-api-krezGsKc.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-B4AtvQHk.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DMxB7slL.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-2fpzufzt.js → chat-terminal-dock-BRrL2iHA.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-fmda2NEP.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-VePLfPUR.js → cron-expression-Bl-2DzBQ.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-CJegmPTJ.js → date-picker-CxTl6Wlz.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-B2o9unBk.js → dependency-picker-DSl0mOPa.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BH4Np-ay.js → desktop-pet-DTeCmCdb.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Duu3ctxD.js → desktop-pet-settings-BNebxg0V.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BBCUZOg2.js → directory-picker-path-field-Dn9XpmXY.js} +1 -1
- package/dist/gateway/static/root/assets/dist-DaxPZj9e.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DY4Af0fY.js → dist-J_ySZvz0.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DS_o3F97.js → extension-debug-page-D-J-eOTb.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BTLBZdCq.js → extension-page-CpST24nU.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-KTGrYbgk.js → extension-settings-page-4nQXFnFq.js} +1 -1
- package/dist/gateway/static/root/assets/floating-ui.dom-B7uQOZZW.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-D3YJVfzY.js → gateway-config-api-BHWHduDi.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BzTbnu4O.js → gateway-config-swr-yUxMMVjK.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-B8--s3yC.js → gateway-settings-BimMKmkM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B2zpkNvi.js → gateway-startup-retry-9mrsL84j.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-MUJ3mEC9.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DSM6aPHF.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BXRjz-iY.js → image-generation-api-CgFAGDi8.js} +1 -1
- package/dist/gateway/static/root/assets/index-B3zYJBhK.js +74 -0
- package/dist/gateway/static/root/assets/index-D3_xSYKd.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D-Ib-suu.js → keyboard-shortcuts-settings-6Ar5rfX4.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-tzM0wTL8.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-Bsy1lvAc.js → local-apps-page-B5n-x544.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-iKjqemWG.js → locale-store-CPylQjH9.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CgoQlera.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-D-akydG4.js → management-settings-CXBLyU-0.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DHH4Cu2i.js → markdown-split-CtmQemJi.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-CUsob4Pz.js +69 -0
- package/dist/gateway/static/root/assets/{media-plugins-BwHtUXkj.js → media-plugins-Dsd-IEOW.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B82nsi9k.js +3 -0
- package/dist/gateway/static/root/assets/notes-api-CfKZYrBC.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-BxM1p6hz.js → notes-page-BKbOTE2n.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BScELo01.js +4 -0
- package/dist/gateway/static/root/assets/oauth-authorization-window-Cdolr2wE.js +1 -0
- package/dist/gateway/static/root/assets/{popover-select-BzdnTy3h.js → popover-select-CccGri5Y.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DrfWH1ir.js → product-open-page-DqB9bsDB.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DUoyty8X.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-PeXUdGdO.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-Cx3JxXSL.js → registry-api-B_5D8epF.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-sHho-uXP.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DF7syQRd.js → runtime-tools-settings-panel-DBTH_t0O.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BQ_qRIsM.js → schema-form-CqMKAwV0.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DyvNgaP9.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CnYf1R7z.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BBHGOQHU.js → settings-form-section-dPriuuYq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-CiwjP2-b.js → settings-loading-skeleton-B-Mbm8Va.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Rl9waapk.js → settings-page-Dyj3w-Ml.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-C4FxY5J3.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-emEdx7YL.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-BQBVq-sN.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BFoEpQ4I.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-YbtR_zEU.js → skills-page-BNtYnrRT.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DTmx2Zza.js → skills-page.utils-DjnbNFs5.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BZDJcKdS.js → system-settings-panel-DDStf-jZ.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-ZVwr8KbS.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BOD2D0dJ.js → theme-store-BN-32Fz5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-Be9aR9qA.js → use-autosave-C2mKZ-ua.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CHjIinCW.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-IMc3Ua6C.js → voice-api-key-field-D7OHeQby.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-TC-xQenr.js → work-discovery-overlay-CIiXie7F.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B2auxcRv.js → workflow-run-setup-panel-9_dAGW3_.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DXpYJxao.js +5 -0
- package/dist/gateway/static/root/index.html +15 -14
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +3 -0
- package/dist/src/agent/agent-manager.d.ts +3 -0
- package/dist/src/agent/agent-manager.js +30 -24
- package/dist/src/agent/embedded/index.d.ts +1 -1
- package/dist/src/agent/embedded/index.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +101 -62
- package/dist/src/agent/embedded/run-turn.js +56 -28
- package/dist/src/agent/embedded/runs.d.ts +16 -29
- package/dist/src/agent/embedded/runs.js +44 -65
- package/dist/src/agent/embedded/types.d.ts +4 -0
- package/dist/src/agent/orchestration/agent-run-supervisor.d.ts +28 -0
- package/dist/src/agent/orchestration/agent-run-supervisor.js +49 -0
- package/dist/src/agent/orchestration/agent-turn-policy.d.ts +18 -0
- package/dist/src/agent/orchestration/agent-turn-policy.js +36 -0
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +34 -4
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +10 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +25 -4
- package/dist/src/agent/service/async-queue.d.ts +16 -3
- package/dist/src/agent/service/async-queue.js +29 -11
- package/dist/src/agent/service/process-direct-streaming.js +27 -4
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/tools/exec-command.d.ts +2 -0
- package/dist/src/agent/tools/exec-command.js +70 -7
- package/dist/src/auth/oauth/index.js +3 -3
- package/dist/src/auth/oauth/registry.d.ts +2 -0
- package/dist/src/auth/oauth/registry.js +20 -12
- package/dist/src/auth/oauth/xopc-cloud.d.ts +1 -0
- package/dist/src/auth/oauth/xopc-cloud.js +32 -16
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/tunnel.js +4 -5
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/schema.d.ts +18 -0
- package/dist/src/config/schema.js +19 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/hono/app.js +2 -1
- package/dist/src/gateway/hono/oauth-async.d.ts +1 -0
- package/dist/src/gateway/hono/oauth-async.js +11 -4
- package/dist/src/gateway/hono/routes/config.js +10 -0
- package/dist/src/gateway/hono/routes/host-fs.js +40 -1
- package/dist/src/gateway/hono/routes/media.js +33 -1
- package/dist/src/gateway/hono/routes/notes.js +162 -7
- package/dist/src/gateway/hono/routes/shares.js +141 -6
- package/dist/src/gateway/hono/routes/tunnel.js +47 -10
- package/dist/src/gateway/hono/routes/voice.d.ts +2 -6
- package/dist/src/gateway/hono/routes/voice.js +20 -4
- package/dist/src/gateway/hono/routes/workflows.js +2 -2
- package/dist/src/gateway/run-loop.js +3 -0
- package/dist/src/gateway/server.d.ts +3 -0
- package/dist/src/gateway/server.js +30 -5
- package/dist/src/gateway/service.js +4 -4
- package/dist/src/notes/service.d.ts +6 -2
- package/dist/src/notes/service.js +36 -4
- package/dist/src/providers/index.js +2 -2
- package/dist/src/share/note-share-service.d.ts +67 -0
- package/dist/src/share/note-share-service.js +283 -0
- package/dist/src/share/share-config.js +32 -3
- package/dist/src/share/share-landing.d.ts +5 -1
- package/dist/src/share/share-landing.js +28 -1
- package/dist/src/share/share-store.d.ts +34 -5
- package/dist/src/share/share-store.js +125 -19
- package/dist/src/share/share-thumbnail.js +4 -2
- package/dist/src/share/share-types.d.ts +52 -14
- package/dist/src/share/share-types.js +9 -0
- package/dist/src/share/share-zip.d.ts +2 -2
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tunnel/env.d.ts +12 -6
- package/dist/src/tunnel/env.js +34 -26
- package/dist/src/tunnel/gateway-lifecycle.js +2 -13
- package/dist/src/tunnel/index.d.ts +1 -1
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/tunnel/tunnel-audit.d.ts +1 -1
- package/dist/src/tunnel/tunnel-config.d.ts +1 -1
- package/dist/src/tunnel/tunnel-config.js +9 -4
- package/dist/src/tunnel/tunnel-service.d.ts +1 -1
- package/dist/src/tunnel/tunnel-service.js +3 -0
- package/dist/src/tunnel/well-known.d.ts +1 -1
- package/dist/src/tunnel/well-known.js +1 -1
- package/dist/src/tunnel/xopc-cloud-registration.d.ts +9 -0
- package/dist/src/tunnel/xopc-cloud-registration.js +42 -0
- package/dist/src/voice/stt/transcribe-core.js +17 -1
- package/dist/src/voice/stt/types.d.ts +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agents-DijFbC4G.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-BFAmf9hq.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-B8us5JBf.js +0 -6
- package/dist/gateway/static/root/assets/block-editor-C3mwGsms.js +0 -184
- package/dist/gateway/static/root/assets/browser-settings-page-BeBd17-3.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Bv0z3KRq.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BczD-pWE.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-2KQYq6xl.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-ByRbxC6z.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-PB1boaNy.js +0 -2
- package/dist/gateway/static/root/assets/dist-C230izr8.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-5YQ5BUwp.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DfIVWJl3.js +0 -1
- package/dist/gateway/static/root/assets/index-BXGC3VFm.css +0 -2
- package/dist/gateway/static/root/assets/index-jqDCfet4.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-CAb0odzu.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-CFxKbDZl.js +0 -2
- package/dist/gateway/static/root/assets/markdown-view-DYkxMtJA.js +0 -69
- package/dist/gateway/static/root/assets/messages-kx5W39dO.js +0 -3
- package/dist/gateway/static/root/assets/notes-api-DJizatxh.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-BGjEC89c.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-Dj9kEQwg.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CBRy5Ezz.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DSwz9RBh.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-WtattyVX.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CNAz_q1F.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CNo4Ajhn.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-B7PI3yZ6.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-DpOH0zWB.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BOf4xCat.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DrMX5Yhj.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-ewIK2ddC.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Bdn82kFQ.js +0 -5
package/dist/src/tunnel/env.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
//#region src/tunnel/env.ts
|
|
2
2
|
const DEV_REGISTRATION_SECRET = "dev-registration-secret";
|
|
3
|
-
const
|
|
3
|
+
const TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE = "TUNNEL_REGISTRATION_SECRET_REQUIRED";
|
|
4
|
+
var TunnelRegistrationSecretError = class extends Error {
|
|
5
|
+
code = TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE;
|
|
6
|
+
constructor(brokerUrl) {
|
|
7
|
+
super(tunnelRegistrationSecretRequiredMessage(brokerUrl));
|
|
8
|
+
this.name = "TunnelRegistrationSecretError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
4
11
|
function brokerHostname(brokerUrl) {
|
|
5
12
|
try {
|
|
6
13
|
const normalized = brokerUrl.includes("://") ? brokerUrl : `https://${brokerUrl}`;
|
|
@@ -9,13 +16,12 @@ function brokerHostname(brokerUrl) {
|
|
|
9
16
|
return null;
|
|
10
17
|
}
|
|
11
18
|
}
|
|
12
|
-
/** True
|
|
13
|
-
function
|
|
19
|
+
/** True only for brokers that are safe to use with the built-in development secret. */
|
|
20
|
+
function isLocalDevelopmentTunnelBroker(brokerUrl) {
|
|
14
21
|
const host = brokerHostname(brokerUrl);
|
|
15
|
-
if (!host) return
|
|
16
|
-
if (host === "localhost" || host === "127.0.0.1" || host === "::1") return
|
|
17
|
-
|
|
18
|
-
return host === "frp.xopc.ai";
|
|
22
|
+
if (!host) return false;
|
|
23
|
+
if (host === "localhost" || host === "127.0.0.1" || host === "::1") return true;
|
|
24
|
+
return host.endsWith(".local");
|
|
19
25
|
}
|
|
20
26
|
function maskTunnelSecretForWeb(secret) {
|
|
21
27
|
const trimmed = secret.trim();
|
|
@@ -23,7 +29,6 @@ function maskTunnelSecretForWeb(secret) {
|
|
|
23
29
|
return "•".repeat(trimmed.length);
|
|
24
30
|
}
|
|
25
31
|
function isMaskedTunnelSecretPatchValue(value) {
|
|
26
|
-
if (TUNNEL_MASKED_SECRET_SENTINELS.includes(value)) return true;
|
|
27
32
|
return /^•+$/.test(value);
|
|
28
33
|
}
|
|
29
34
|
function effectiveBrokerUrl(brokerUrl, env) {
|
|
@@ -37,37 +42,40 @@ function readTunnelRegistrationSecretFromConfigOnly(config) {
|
|
|
37
42
|
return config?.tunnel?.registrationSecret?.trim() || null;
|
|
38
43
|
}
|
|
39
44
|
function getTunnelRegistrationSecretMeta(config, env = process.env, brokerUrl) {
|
|
40
|
-
if (env.XOPC_TUNNEL_REGISTRATION_SECRET?.trim()) return {
|
|
41
|
-
configured: true,
|
|
42
|
-
source: "env"
|
|
43
|
-
};
|
|
44
45
|
if (config?.tunnel?.registrationSecret?.trim()) return {
|
|
45
46
|
configured: true,
|
|
46
47
|
source: "config"
|
|
47
48
|
};
|
|
48
|
-
if (
|
|
49
|
-
configured: false,
|
|
50
|
-
source: "missing"
|
|
51
|
-
};
|
|
52
|
-
return {
|
|
49
|
+
if (isLocalDevelopmentTunnelBroker(effectiveBrokerUrl(brokerUrl ?? config?.tunnel?.brokerUrl, env))) return {
|
|
53
50
|
configured: true,
|
|
54
51
|
source: "dev_default"
|
|
55
52
|
};
|
|
53
|
+
return {
|
|
54
|
+
configured: false,
|
|
55
|
+
source: "missing"
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function resolveOptionalTunnelRegistrationSecret(brokerUrl, configSecret) {
|
|
59
|
+
const fromConfig = configSecret?.trim();
|
|
60
|
+
if (fromConfig) return fromConfig;
|
|
61
|
+
return isLocalDevelopmentTunnelBroker(effectiveBrokerUrl(brokerUrl, process.env)) ? DEV_REGISTRATION_SECRET : void 0;
|
|
62
|
+
}
|
|
63
|
+
function tunnelRegistrationSecretRequiredMessage(brokerUrl) {
|
|
64
|
+
const effectiveUrl = effectiveBrokerUrl(brokerUrl, process.env);
|
|
65
|
+
const host = brokerHostname(effectiveUrl);
|
|
66
|
+
return `Tunnel registration secret is required for ${host === "frp.xopc.ai" ? "the XOPC public broker (frp.xopc.ai)" : `broker ${host ?? effectiveUrl}`}. Authorize XOPC from Remote access → Public internet, or create a Tunnel Registration Key at https://console.xopc.ai/access/client and save it there manually.`;
|
|
56
67
|
}
|
|
57
68
|
/**
|
|
58
69
|
* Registration secret for Tunnel Broker register API.
|
|
59
|
-
*
|
|
70
|
+
* Resolve `tunnel.registrationSecret` from config, with a development default for local brokers.
|
|
60
71
|
*/
|
|
61
|
-
function resolveTunnelRegistrationSecret(
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
if (fromConfig) return fromConfig;
|
|
66
|
-
if (isProductionTunnelBroker(effectiveBrokerUrl(brokerUrl, env))) throw new Error("Tunnel registration secret is required for the production broker (frp.xopc.ai). Create a Tunnel Registration Key at https://console.xopc.ai/keys/tunnel and save it under Remote access → Public internet.");
|
|
67
|
-
return DEV_REGISTRATION_SECRET;
|
|
72
|
+
function resolveTunnelRegistrationSecret(brokerUrl, configSecret) {
|
|
73
|
+
const secret = resolveOptionalTunnelRegistrationSecret(brokerUrl, configSecret);
|
|
74
|
+
if (secret) return secret;
|
|
75
|
+
throw new TunnelRegistrationSecretError(brokerUrl);
|
|
68
76
|
}
|
|
69
77
|
function resolveTunnelBrokerUrl(configBrokerUrl, env = process.env) {
|
|
70
78
|
return env.XOPC_TUNNEL_BROKER_URL ?? configBrokerUrl ?? "https://frp.xopc.ai/api";
|
|
71
79
|
}
|
|
72
80
|
//#endregion
|
|
73
|
-
export {
|
|
81
|
+
export { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, isLocalDevelopmentTunnelBroker, isMaskedTunnelSecretPatchValue, maskTunnelSecretForWeb, readTunnelRegistrationSecretFromConfigOnly, resolveOptionalTunnelRegistrationSecret, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret, tunnelRegistrationSecretRequiredMessage };
|
|
@@ -2,7 +2,7 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { resolveGatewayEffectiveHost } from "../config/gateway-bind.js";
|
|
4
4
|
import { hasValidTunnelConsent } from "./consent.js";
|
|
5
|
-
import {
|
|
5
|
+
import { resolveOptionalTunnelRegistrationSecret, resolveTunnelBrokerUrl } from "./env.js";
|
|
6
6
|
import { getTunnelService } from "./tunnel-service.js";
|
|
7
7
|
import { resolveFrpSubdomainHost } from "./frp-subdomain-host.js";
|
|
8
8
|
import { fetchTunnelWellKnown } from "./well-known.js";
|
|
@@ -25,20 +25,9 @@ function wireTunnelEventsToGateway(service) {
|
|
|
25
25
|
tunnel.on("tunnel:progress", publish);
|
|
26
26
|
}
|
|
27
27
|
function applyTunnelServiceFromGatewayConfig(config, brokerUrl) {
|
|
28
|
-
let registrationSecret;
|
|
29
|
-
try {
|
|
30
|
-
registrationSecret = resolveTunnelRegistrationSecret(process.env, brokerUrl, config.tunnel?.registrationSecret);
|
|
31
|
-
} catch (err) {
|
|
32
|
-
const em = err instanceof Error ? err.message : String(err);
|
|
33
|
-
log.warn({
|
|
34
|
-
phase: "tunnel_configure",
|
|
35
|
-
errorMessage: em
|
|
36
|
-
}, em);
|
|
37
|
-
throw err;
|
|
38
|
-
}
|
|
39
28
|
getTunnelService().configure({
|
|
40
29
|
brokerUrl,
|
|
41
|
-
registrationSecret,
|
|
30
|
+
registrationSecret: resolveOptionalTunnelRegistrationSecret(brokerUrl, config.tunnel?.registrationSecret),
|
|
42
31
|
autoStart: config.tunnel?.autoStart ?? false,
|
|
43
32
|
gatewayHost: resolveGatewayEffectiveHost(config),
|
|
44
33
|
frpSubdomainHost: resolveFrpSubdomainHost(brokerUrl)
|
|
@@ -6,7 +6,7 @@ export type { EnsureFrpcBinaryOptions, FrpcDownloadProgress } from './frpc-binar
|
|
|
6
6
|
export { configureTunnelFromGatewayConfig, maybeAutoStartTunnelFromConfig, wireTunnelEventsToGateway, } from './gateway-lifecycle.js';
|
|
7
7
|
export { fetchTunnelWellKnown, clearTunnelWellKnownCache } from './well-known.js';
|
|
8
8
|
export type { TunnelWellKnownConfig, TunnelWellKnownTransport } from './well-known.js';
|
|
9
|
-
export { getTunnelRegistrationSecretMeta,
|
|
9
|
+
export { getTunnelRegistrationSecretMeta, isLocalDevelopmentTunnelBroker, isMaskedTunnelSecretPatchValue, resolveTunnelBrokerUrl, resolveOptionalTunnelRegistrationSecret, resolveTunnelRegistrationSecret, TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, tunnelRegistrationSecretRequiredMessage, TunnelRegistrationSecretError, } from './env.js';
|
|
10
10
|
export type { TunnelRegistrationSecretMeta, TunnelRegistrationSecretSource } from './env.js';
|
|
11
11
|
export { logTunnelAudit } from './tunnel-audit.js';
|
|
12
12
|
export type { TunnelAuditEvent } from './tunnel-audit.js';
|
package/dist/src/tunnel/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { loadTunnelState, resolveTunnelStatePath, saveTunnelState } from "./tunnel-state.js";
|
|
2
2
|
import { buildMobileConnectQrPayload, resolveLanGatewayUrl } from "./tunnel-qr.js";
|
|
3
3
|
import { CURRENT_TUNNEL_CONSENT_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState, hasValidTunnelConsent } from "./consent.js";
|
|
4
|
-
import { getTunnelRegistrationSecretMeta, isMaskedTunnelSecretPatchValue,
|
|
4
|
+
import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, isLocalDevelopmentTunnelBroker, isMaskedTunnelSecretPatchValue, resolveOptionalTunnelRegistrationSecret, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret, tunnelRegistrationSecretRequiredMessage } from "./env.js";
|
|
5
5
|
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
6
6
|
import { FRPC_VERSION, clearFrpcPathForProcess, ensureFrpcBinary, publishFrpcPathForProcess } from "./frpc-binary.js";
|
|
7
7
|
import { consumePairingSecret, createPairingSecret, resetPairingSessionsForTests } from "./pairing.js";
|
|
@@ -12,4 +12,4 @@ import { clearTunnelWellKnownCache, fetchTunnelWellKnown } from "./well-known.js
|
|
|
12
12
|
import { configureTunnelFromGatewayConfig, maybeAutoStartTunnelFromConfig, wireTunnelEventsToGateway } from "./gateway-lifecycle.js";
|
|
13
13
|
import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, sanitizeTunnelConfig, setTunnelEnabledInConfig } from "./tunnel-config.js";
|
|
14
14
|
import { consumeTunnelMutationLimit, resetTunnelMutationLimitsForTests } from "./tunnel-rate-limit.js";
|
|
15
|
-
export { CURRENT_TUNNEL_CONSENT_VERSION, FRPC_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelBrokerClient, TunnelConsentError, TunnelService, applyTunnelConsentToConfig, assertTunnelMayStart, buildMobileConnectQrPayload, clearFrpcPathForProcess, clearTunnelWellKnownCache, configureTunnelFromGatewayConfig, consumePairingSecret, consumeTunnelMutationLimit, createPairingSecret, ensureFrpcBinary, fetchTunnelWellKnown, getTunnelConsentState, getTunnelRegistrationSecretMeta, getTunnelService, hasValidTunnelConsent, hashGatewayToken,
|
|
15
|
+
export { CURRENT_TUNNEL_CONSENT_VERSION, FRPC_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelBrokerClient, TunnelConsentError, TunnelRegistrationSecretError, TunnelService, applyTunnelConsentToConfig, assertTunnelMayStart, buildMobileConnectQrPayload, clearFrpcPathForProcess, clearTunnelWellKnownCache, configureTunnelFromGatewayConfig, consumePairingSecret, consumeTunnelMutationLimit, createPairingSecret, ensureFrpcBinary, fetchTunnelWellKnown, getTunnelConsentState, getTunnelRegistrationSecretMeta, getTunnelService, hasValidTunnelConsent, hashGatewayToken, isLocalDevelopmentTunnelBroker, isMaskedTunnelSecretPatchValue, loadTunnelState, logTunnelAudit, maybeAutoStartTunnelFromConfig, mergeTunnelConfigPatch, publishFrpcPathForProcess, resetPairingSessionsForTests, resetTunnelMutationLimitsForTests, resolveBrokerApiBase, resolveFrpSubdomainHost, resolveLanGatewayUrl, resolveOptionalTunnelRegistrationSecret, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret, resolveTunnelStatePath, sanitizeTunnelConfig, saveTunnelState, setTunnelEnabledInConfig, tunnelRegistrationSecretRequiredMessage, wireTunnelEventsToGateway };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type TunnelAuditEvent = 'tunnel.consent' | 'tunnel.start' | 'tunnel.stop' | 'tunnel.release' | 'tunnel.start_denied' | 'tunnel.pair' | 'tunnel.exchange_token' | 'tunnel.enable_lan_pairing';
|
|
1
|
+
export type TunnelAuditEvent = 'tunnel.consent' | 'tunnel.start' | 'tunnel.stop' | 'tunnel.release' | 'tunnel.start_denied' | 'tunnel.pair' | 'tunnel.exchange_token' | 'tunnel.registration_authorized' | 'tunnel.enable_lan_pairing';
|
|
2
2
|
export declare function logTunnelAudit(event: TunnelAuditEvent, fields: Record<string, unknown>, message: string): void;
|
|
@@ -8,7 +8,7 @@ export declare function mergeTunnelConfigPatch(config: Config, patch: Record<str
|
|
|
8
8
|
export declare function applyTunnelConsentToConfig(config: Config): void;
|
|
9
9
|
export declare function setTunnelEnabledInConfig(config: Config, enabled: boolean): void;
|
|
10
10
|
/**
|
|
11
|
-
* Clear stale tunnel flags when consent
|
|
11
|
+
* Clear stale tunnel flags when consent or broker credentials cannot support a start.
|
|
12
12
|
* Returns true when `config.tunnel` was modified.
|
|
13
13
|
*/
|
|
14
14
|
export declare function sanitizeTunnelConfig(config: Config): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TunnelConfigSchema, TunnelConsentSchema, init_schema } from "../config/schema.js";
|
|
2
2
|
import { assertTunnelAutoStartAllowed, buildTunnelConsentRecord, hasValidTunnelConsent } from "./consent.js";
|
|
3
|
-
import { isMaskedTunnelSecretPatchValue } from "./env.js";
|
|
3
|
+
import { getTunnelRegistrationSecretMeta, isMaskedTunnelSecretPatchValue } from "./env.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/tunnel/tunnel-config.ts
|
|
6
6
|
init_schema();
|
|
@@ -29,7 +29,11 @@ function mergeTunnelConfigPatch(config, patch) {
|
|
|
29
29
|
...config.tunnel ?? TunnelConfigSchema.parse({}),
|
|
30
30
|
...patchFields
|
|
31
31
|
};
|
|
32
|
-
if (parsed.data.registrationSecret === null)
|
|
32
|
+
if (parsed.data.registrationSecret === null) {
|
|
33
|
+
delete next.registrationSecret;
|
|
34
|
+
next.enabled = false;
|
|
35
|
+
next.autoStart = false;
|
|
36
|
+
}
|
|
33
37
|
if (parsed.data.autoStart === true) {
|
|
34
38
|
const probeTunnel = TunnelConfigSchema.parse({
|
|
35
39
|
...next,
|
|
@@ -67,13 +71,14 @@ function setTunnelEnabledInConfig(config, enabled) {
|
|
|
67
71
|
config.tunnel.enabled = enabled;
|
|
68
72
|
}
|
|
69
73
|
/**
|
|
70
|
-
* Clear stale tunnel flags when consent
|
|
74
|
+
* Clear stale tunnel flags when consent or broker credentials cannot support a start.
|
|
71
75
|
* Returns true when `config.tunnel` was modified.
|
|
72
76
|
*/
|
|
73
77
|
function sanitizeTunnelConfig(config) {
|
|
74
78
|
const tunnel = config.tunnel;
|
|
75
79
|
if (!tunnel) return false;
|
|
76
|
-
|
|
80
|
+
const brokerReady = getTunnelRegistrationSecretMeta(config).configured;
|
|
81
|
+
if (hasValidTunnelConsent(config) && brokerReady) return false;
|
|
77
82
|
let changed = false;
|
|
78
83
|
if (tunnel.enabled) {
|
|
79
84
|
tunnel.enabled = false;
|
|
@@ -2,7 +2,7 @@ import { EventEmitter } from 'node:events';
|
|
|
2
2
|
import type { TunnelQrPayload, TunnelStatus } from './tunnel-types.js';
|
|
3
3
|
export type TunnelServiceConfig = {
|
|
4
4
|
brokerUrl: string;
|
|
5
|
-
registrationSecret
|
|
5
|
+
registrationSecret?: string;
|
|
6
6
|
autoStart: boolean;
|
|
7
7
|
gatewayHost: string;
|
|
8
8
|
frpSubdomainHost: string;
|
|
@@ -3,6 +3,7 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
4
|
import { clearTunnelState, loadTunnelState, saveTunnelState, updateTunnelState } from "./tunnel-state.js";
|
|
5
5
|
import { buildMobileConnectQrPayload, resolveLanGatewayUrl } from "./tunnel-qr.js";
|
|
6
|
+
import { TunnelRegistrationSecretError } from "./env.js";
|
|
6
7
|
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
7
8
|
import { clearFrpcPathForProcess, ensureFrpcBinary, publishFrpcPathForProcess } from "./frpc-binary.js";
|
|
8
9
|
import { writeFrpcConfig } from "./frpc-config.js";
|
|
@@ -230,6 +231,7 @@ var TunnelService = class extends EventEmitter {
|
|
|
230
231
|
phase: "tunnel_resume"
|
|
231
232
|
}, "Persisted tunnel not resumable — registering again");
|
|
232
233
|
}
|
|
234
|
+
if (!cfg.registrationSecret) throw new TunnelRegistrationSecretError(cfg.brokerUrl);
|
|
233
235
|
return broker.register({
|
|
234
236
|
brokerUrl: resolveBrokerApiBase(cfg.brokerUrl),
|
|
235
237
|
registrationSecret: cfg.registrationSecret,
|
|
@@ -319,6 +321,7 @@ var TunnelService = class extends EventEmitter {
|
|
|
319
321
|
const cfg = this.serviceConfig;
|
|
320
322
|
if (!ctx || !cfg) return;
|
|
321
323
|
try {
|
|
324
|
+
if (!cfg.registrationSecret) throw new TunnelRegistrationSecretError(cfg.brokerUrl);
|
|
322
325
|
const registration = await broker.register({
|
|
323
326
|
brokerUrl: resolveBrokerApiBase(cfg.brokerUrl),
|
|
324
327
|
registrationSecret: cfg.registrationSecret,
|
|
@@ -15,7 +15,7 @@ export type TunnelWellKnownConfig = {
|
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Fetch `/.well-known/tunnel-config` (broker URL, frp endpoints, frpc version).
|
|
18
|
-
* Registration
|
|
18
|
+
* Registration secrets are never published here.
|
|
19
19
|
*/
|
|
20
20
|
export declare function fetchTunnelWellKnown(brokerUrl: string): Promise<TunnelWellKnownConfig>;
|
|
21
21
|
export declare function pingTunnelBroker(brokerUrl: string): Promise<boolean>;
|
|
@@ -10,7 +10,7 @@ function brokerOrigin(brokerUrl) {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Fetch `/.well-known/tunnel-config` (broker URL, frp endpoints, frpc version).
|
|
13
|
-
* Registration
|
|
13
|
+
* Registration secrets are never published here.
|
|
14
14
|
*/
|
|
15
15
|
async function fetchTunnelWellKnown(brokerUrl) {
|
|
16
16
|
const origin = brokerOrigin(brokerUrl);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type ProvisionOptions = {
|
|
2
|
+
fetchImpl?: typeof fetch;
|
|
3
|
+
routerUrl?: string;
|
|
4
|
+
resolveAccessToken?: () => Promise<string | null>;
|
|
5
|
+
deviceName?: string;
|
|
6
|
+
};
|
|
7
|
+
/** Exchange a narrowly scoped XOPC OAuth grant for a tunnel registration key. */
|
|
8
|
+
export declare function provisionTunnelRegistrationKey(options?: ProvisionOptions): Promise<string>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CredentialResolver, init_credentials } from "../auth/credentials.js";
|
|
2
|
+
import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "../providers/xopc-cloud-config.js";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/tunnel/xopc-cloud-registration.ts
|
|
6
|
+
init_credentials();
|
|
7
|
+
init_xopc_cloud_config();
|
|
8
|
+
const registrationResponseSchema = z.object({ key: z.string().min(1) });
|
|
9
|
+
function responseError(body, status) {
|
|
10
|
+
if (body && typeof body === "object") {
|
|
11
|
+
const error = body.error;
|
|
12
|
+
if (error && typeof error === "object") {
|
|
13
|
+
const message = error.message;
|
|
14
|
+
if (typeof message === "string" && message.trim()) return message;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return `Tunnel registration failed (${status})`;
|
|
18
|
+
}
|
|
19
|
+
/** Exchange a narrowly scoped XOPC OAuth grant for a tunnel registration key. */
|
|
20
|
+
async function provisionTunnelRegistrationKey(options = {}) {
|
|
21
|
+
const accessToken = await (options.resolveAccessToken ?? (() => new CredentialResolver().resolveApiKey("xopc-tunnel")))();
|
|
22
|
+
if (!accessToken) throw new Error("Authorize XOPC Public Tunnel before creating a registration key");
|
|
23
|
+
const routerUrl = resolveXopcModelRouterUrl(options.routerUrl);
|
|
24
|
+
const deviceName = options.deviceName?.trim() || hostname() || "XOPC gateway";
|
|
25
|
+
const response = await (options.fetchImpl ?? fetch)(`${routerUrl}/tunnel/registration-key`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
authorization: `Bearer ${accessToken}`,
|
|
29
|
+
accept: "application/json",
|
|
30
|
+
"content-type": "application/json"
|
|
31
|
+
},
|
|
32
|
+
body: JSON.stringify({ name: deviceName.slice(0, 64) }),
|
|
33
|
+
signal: AbortSignal.timeout(3e4)
|
|
34
|
+
});
|
|
35
|
+
const body = await response.json().catch(() => null);
|
|
36
|
+
if (!response.ok) throw new Error(responseError(body, response.status));
|
|
37
|
+
const parsed = registrationResponseSchema.safeParse(body);
|
|
38
|
+
if (!parsed.success) throw new Error("Tunnel registration returned an invalid response");
|
|
39
|
+
return parsed.data.key;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { provisionTunnelRegistrationKey };
|
|
@@ -10,6 +10,7 @@ function classifyFailureReason(reason) {
|
|
|
10
10
|
const lower = reason.toLowerCase();
|
|
11
11
|
if (lower.includes("not configured") || lower.includes("api key") || lower.includes("missing")) return "not_configured";
|
|
12
12
|
if (lower.includes("timeout") || lower.includes("timed out") || lower.includes("aborted")) return "timeout";
|
|
13
|
+
if (lower.includes("empty transcription") || lower.includes("no speech") || lower.includes("no voice detected")) return "no_speech";
|
|
13
14
|
if (lower.includes("unsupported") || lower.includes("format") || lower.includes("audio decoder")) return "unsupported_format";
|
|
14
15
|
return "provider_error";
|
|
15
16
|
}
|
|
@@ -51,7 +52,23 @@ async function transcribe(audioBuffer, config, options) {
|
|
|
51
52
|
const attachmentDecision = result.decision.attachments[0];
|
|
52
53
|
const attempts = (attachmentDecision?.attempts ?? []).map(toAttempt);
|
|
53
54
|
const attemptedProviders = attempts.map((a) => a.provider);
|
|
55
|
+
const primaryProvider = providersWithLanguage[0].id;
|
|
54
56
|
if (!attachmentDecision?.chosen) {
|
|
57
|
+
const noSpeechAttempt = attempts.findLast((attempt) => attempt.reasonCode === "no_speech");
|
|
58
|
+
if (noSpeechAttempt) {
|
|
59
|
+
log.debug({
|
|
60
|
+
attempts,
|
|
61
|
+
attemptedProviders
|
|
62
|
+
}, "STT completed without recognized speech");
|
|
63
|
+
const fallbackFrom = noSpeechAttempt.provider !== primaryProvider ? primaryProvider : void 0;
|
|
64
|
+
return {
|
|
65
|
+
text: "",
|
|
66
|
+
provider: noSpeechAttempt.provider,
|
|
67
|
+
attempts,
|
|
68
|
+
...fallbackFrom ? { fallbackFrom } : {},
|
|
69
|
+
attemptedProviders
|
|
70
|
+
};
|
|
71
|
+
}
|
|
55
72
|
log.error({
|
|
56
73
|
attempts,
|
|
57
74
|
attemptedProviders
|
|
@@ -62,7 +79,6 @@ async function transcribe(audioBuffer, config, options) {
|
|
|
62
79
|
const chosen = attachmentDecision.chosen;
|
|
63
80
|
const output = result.outputs[0];
|
|
64
81
|
if (!output) throw new Error("STT runner returned chosen attempt but no output text");
|
|
65
|
-
const primaryProvider = providersWithLanguage[0].id;
|
|
66
82
|
const fallbackFrom = chosen.provider && chosen.provider !== primaryProvider ? primaryProvider : void 0;
|
|
67
83
|
return {
|
|
68
84
|
text: output.text,
|
|
@@ -47,7 +47,7 @@ export interface STTConfig {
|
|
|
47
47
|
timeoutMs?: number;
|
|
48
48
|
}
|
|
49
49
|
export type STTProviderAttemptTask = 'success' | 'skipped' | 'failed';
|
|
50
|
-
export type STTProviderFailureReason = 'success' | 'not_configured' | 'timeout' | 'provider_error' | 'unsupported_format' | 'unknown';
|
|
50
|
+
export type STTProviderFailureReason = 'success' | 'not_configured' | 'timeout' | 'no_speech' | 'provider_error' | 'unsupported_format' | 'unknown';
|
|
51
51
|
export interface STTProviderAttempt {
|
|
52
52
|
provider: string;
|
|
53
53
|
task: STTProviderAttemptTask;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.224",
|
|
4
4
|
"description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -157,9 +157,9 @@
|
|
|
157
157
|
"vitepress": "^1.6.4",
|
|
158
158
|
"vitest": "4.1.5",
|
|
159
159
|
"vue": "^3.5.35",
|
|
160
|
+
"@xopcai/gateway-contract": "0.0.0",
|
|
160
161
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
161
162
|
"@xopcai/realtime-protocol": "0.0.0",
|
|
162
|
-
"@xopcai/gateway-contract": "0.0.0",
|
|
163
163
|
"@xopcai/realtime-client": "0.0.0"
|
|
164
164
|
},
|
|
165
165
|
"scripts": {
|