@xopcai/xopc 0.0.253 → 0.0.255
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/dist/background.js +59 -13
- package/dist/browser-ext/dist/content.js +0 -5
- package/dist/browser-ext/manifest.json +2 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CeS1bgXP.js → activity-store-DvjK5FEm.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BdF3HhCW.js → agent-avatar-dicebear-Cqspzbf_.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CL3Mi-uM.js +1 -0
- package/dist/gateway/static/root/assets/agents-odqXmGhA.js +1 -0
- package/dist/gateway/static/root/assets/{api-zMPeC0yU.js → api-CsYi3heY.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BaAFln8W.js → app-management-settings-panel-Gd4a5hdE.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CXvsoBlw.js → appearance-settings-CZ6KOnbd.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DyBDoCam.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-C0o_mVQI.js → archive-plugin-y82Rwhjm.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-B5Ry3tGL.js → attachment-load-D46SGNpv.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DY5QAEQd.js → automations-page-wilciIZ1.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-8U86Umig.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BydpEgBA.js → binary-plugins-CuMkNNCe.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D0CpUOMo.js → block-editor-DFnPsrxI.js} +44 -44
- package/dist/gateway/static/root/assets/{browser-automation-inputs-DzbTsGI6.js → browser-automation-inputs-hlmcSp4p.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-D7fZYjni.js → browser-automations-page-OjZvbARU.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-DOUG84qV.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CG73Mwi8.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-MDywEWWM.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-BGGRTkn6.js → channels-status-swr-D1HHFzkE.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-_CP4nvlg.js → chat-terminal-dock-Ce_T9BPq.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-D29p6Zvm.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-g2U8Rllf.js → cron-expression-BRrCwYyD.js} +1 -1
- package/dist/gateway/static/root/assets/date-picker-C35RuuWW.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-D-0gcbbM.js → dependency-picker-4pNXVcRM.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-D7kvWQ9H.js → desktop-pet-settings-BvV1UA5g.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Cl3JRIu6.js → desktop-pet-z91GYnPf.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DtP2tJHY.js → extension-debug-page-CkVF5HvV.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CphZDdoT.js → extension-page-DW0zQGaB.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CsxVLV4-.js → extension-settings-page-BLQhizZ3.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BW3Bx-aV.js → gateway-config-swr-02BBC1mK.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DxBZ05dX.js → gateway-settings-rAXx8FGP.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DAq74TZe.js → gateway-startup-retry-XZnY6621.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-BaW_r1t9.js +1 -0
- package/dist/gateway/static/root/assets/home-page-BoTS8-Z9.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-MPuaXDRs.js → image-generation-api-CIcKz4Xs.js} +1 -1
- package/dist/gateway/static/root/assets/index-DsonmRCH.css +2 -0
- package/dist/gateway/static/root/assets/index-PksHo9hS.js +74 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfhaTqgE.js → keyboard-shortcuts-settings-yfaGz6SE.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-CR6asX7L.js → local-app-workbench-page-B3flRQH1.js} +2 -2
- package/dist/gateway/static/root/assets/{local-apps-page-g01W3kEK.js → local-apps-page-Cp-nEtgV.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-BkeaPZpn.js → locale-store-VsboRLD7.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DkqsRCri.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-DeGxJF_Z.js → management-settings-24_JyDPk.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-Ca7BRBLL.js → markdown-view-CPXhy6nh.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-FmOhmzlD.js → media-plugins-CwLvIb9r.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DngsF_Kx.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-BXNbn05L.js → mobile-pairing-wizard-BbJCDv57.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-OklYXK7y.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BjfgJIQw.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-pyukZ1PJ.js → page-tabs-0YXn9Gkl.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-slFHoMUe.js → preview-open-alternatives-2jVV5kfZ.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CXa3FNNk.js → product-open-page-D7p0NfTK.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-rLNM2mP0.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-D6jY2ZWl.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-CviQoUBf.js → registry-api-DlTWbXQA.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CZZg0kXc.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-O9D9o7-O.js → runtime-tools-settings-panel-B-NDgmJ4.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-8FesicnL.js → schema-form-DZYeBS1v.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BvuxJegi.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BAQHP4mB.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CBic9TFH.js → settings-form-section-zy5UMvPk.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Xz66_Mjg.js → settings-page-CTuipbJq.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BkWoc5j5.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page--JpjwB58.js → share-preview-page-D3Uawo_h.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-B2doziIn.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-D2ymjqG5.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-fVKExKv5.js → skills-page-DDbabz7p.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-Yv9u3uJp.js → skills-page.utils-DkGhbiMa.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CCWjVdc2.js → system-settings-panel-Fc-WbX6-.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-7w7eB9nB.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BtkaVpMm.js → theme-store-vdB57bTn.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-C__W9BaN.js → tunnel-api-DZ0evABj.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-Dow9RRcq.js → use-autosave-Ckof_m7e.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CcNCyrXZ.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CvF3lEyx.js → voice-api-key-field-CnmtpWlq.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-BEUVAyM6.js → voice-config-api-OA04c71t.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-B9PDfReq.js → work-discovery-overlay-sxvsDIC3.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-CUCfBpPF.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-Bp-nvnLa.js +5 -0
- package/dist/gateway/static/root/index.html +11 -11
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +17 -2
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +85 -1
- package/dist/src/agent/tools/browser/tool/schemas.js +212 -5
- package/dist/src/agent/tools/create-share-tool.js +39 -1
- package/dist/src/agent/tools/xopc-use-tool.js +2 -2
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/drivers/extension-driver.d.ts +4 -4
- package/dist/src/browser/drivers/extension-driver.js +20 -8
- package/dist/src/browser/drivers/playwright-driver.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +3 -0
- package/dist/src/browser/providers/browser-ext-install.js +19 -4
- package/dist/src/browser/providers/extension.d.ts +14 -1
- package/dist/src/browser/providers/extension.js +89 -11
- package/dist/src/browser/providers/playwright-install.js +8 -12
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/tunnel.js +3 -3
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/device-routes.js +1 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/routes/browser.js +149 -27
- package/dist/src/gateway/hono/routes/lazy-bundles.js +3 -3
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +404 -7
- package/dist/src/gateway/hono/routes/site-shares.js +19 -13
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +2 -2
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/sessions-api.js +1 -1
- package/dist/src/gateway/service.js +13 -13
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/model-thinking.js +57 -20
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/remote-access/exposure-manager.js +1 -1
- package/dist/src/session/index.js +1 -1
- package/dist/src/session/store.js +1 -1
- package/dist/src/share/hosted-note-publication.d.ts +22 -0
- package/dist/src/share/hosted-note-publication.js +96 -0
- package/dist/src/share/hosted-session-share.d.ts +86 -7
- package/dist/src/share/hosted-session-share.js +72 -15
- package/dist/src/share/hosted-static-site-publication.d.ts +16 -0
- package/dist/src/share/hosted-static-site-publication.js +108 -0
- package/dist/src/share/hosted-static-site-publish.d.ts +23 -0
- package/dist/src/share/hosted-static-site-publish.js +53 -0
- package/dist/src/share/note-share-service.d.ts +1 -0
- package/dist/src/share/note-share-service.js +4 -4
- package/dist/src/share/share-url.d.ts +1 -1
- package/dist/src/share/share-url.js +14 -9
- package/dist/src/tasks/home-query-service.js +2 -2
- package/dist/src/tui/backends/embedded-backend.js +2 -2
- package/dist/src/tui/tui-agent-events.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/tunnel/index.js +1 -1
- package/dist/src/tunnel/tunnel-service.js +1 -1
- package/dist/src/voice/realtime/agentEngine.js +17 -0
- package/dist/src/voice/realtime/memory-context.js +1 -1
- package/dist/src/voice/realtime/playback-echo.d.ts +2 -0
- package/dist/src/voice/realtime/playback-echo.js +15 -0
- package/dist/src/work-discovery/service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +2 -2
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Bs34Kp0K.js +0 -1
- package/dist/gateway/static/root/assets/agents-DARlgjTm.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BhgvfBJT.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BzX4lILP.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BBdMqxl0.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-D_WfftDW.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-bdRLT9KA.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CPDjU5wU.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-SmVlhtj_.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-DWcKsIoZ.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BdvLZKQZ.js +0 -1
- package/dist/gateway/static/root/assets/index-C7RDs6S-.js +0 -74
- package/dist/gateway/static/root/assets/index-Cu8xqZQ9.css +0 -2
- package/dist/gateway/static/root/assets/logs-page-ZP4QTWoC.js +0 -2
- package/dist/gateway/static/root/assets/messages-C72stReU.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-EeVeF4II.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-D7bMff96.js +0 -8
- package/dist/gateway/static/root/assets/popover-select-C-Hj-nXR.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-BDF88VdN.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DeTD6pu1.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CxKrdQ6a.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DUFJN-2t.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CcSYDjaH.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-C6DuwrP5.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CovcdHSC.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CrHagTsE.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-I8hueJnG.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-CU6nxmoM.js +0 -2
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-kWGFkhjz.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-B4Is5E42.js +0 -5
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
2
|
+
import { resolveMimeType } from "./share-store.js";
|
|
3
|
+
import { basename, dirname, extname, posix, relative, resolve } from "node:path";
|
|
4
|
+
import { createReadStream } from "node:fs";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import { lstat, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
+
//#region src/share/hosted-static-site-publication.ts
|
|
8
|
+
const MAX_FILES = 2e3;
|
|
9
|
+
const MAX_FILE_BYTES = 64 * 1024 * 1024;
|
|
10
|
+
const MAX_TOTAL_BYTES = 512 * 1024 * 1024;
|
|
11
|
+
var HostedStaticSitePublicationBuilder = class {
|
|
12
|
+
async build(workspaceRoot, input) {
|
|
13
|
+
const realSource = await realpath(resolve(workspaceRoot, normalizeInputPath(input.path)));
|
|
14
|
+
if (!isPathUnderWorkspace(workspaceRoot, realSource)) throw new Error("Static site path is outside the workspace");
|
|
15
|
+
const sourceStat = await stat(realSource);
|
|
16
|
+
const singleHtml = sourceStat.isFile();
|
|
17
|
+
if (singleHtml && resolveMimeType(realSource) !== "text/html") throw new Error("Static site file must be an HTML document");
|
|
18
|
+
if (!singleHtml && !sourceStat.isDirectory()) throw new Error("Static site source must be an HTML file or directory");
|
|
19
|
+
const rootDir = singleHtml ? dirname(realSource) : realSource;
|
|
20
|
+
const entries = singleHtml ? [{
|
|
21
|
+
path: "index.html",
|
|
22
|
+
absolutePath: realSource
|
|
23
|
+
}] : (await collectFiles(rootDir)).map((path) => ({
|
|
24
|
+
path,
|
|
25
|
+
absolutePath: resolve(rootDir, path)
|
|
26
|
+
}));
|
|
27
|
+
if (!singleHtml && !entries.some((entry) => entry.path === "index.html")) throw new Error("Static site must contain index.html");
|
|
28
|
+
const assets = [];
|
|
29
|
+
const files = [];
|
|
30
|
+
let totalBytes = 0;
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const filePath = entry.path;
|
|
33
|
+
const absolutePath = entry.absolutePath;
|
|
34
|
+
const fileStat = await stat(absolutePath);
|
|
35
|
+
if (fileStat.size > MAX_FILE_BYTES) throw new Error(`Static site file exceeds publishing limit: ${filePath}`);
|
|
36
|
+
totalBytes += fileStat.size;
|
|
37
|
+
if (totalBytes > MAX_TOTAL_BYTES) throw new Error("Static site exceeds total publishing limit");
|
|
38
|
+
const id = createHash("sha256").update(filePath).digest("hex").slice(0, 40);
|
|
39
|
+
assets.push({
|
|
40
|
+
id,
|
|
41
|
+
path: absolutePath,
|
|
42
|
+
size: fileStat.size
|
|
43
|
+
});
|
|
44
|
+
files.push({
|
|
45
|
+
id,
|
|
46
|
+
path: filePath,
|
|
47
|
+
mimeType: resolveMimeType(filePath),
|
|
48
|
+
size: fileStat.size,
|
|
49
|
+
sha256: await sha256File(absolutePath)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const defaultTitle = singleHtml ? basename(realSource, extname(realSource)) : basename(realSource);
|
|
53
|
+
const title = input.title?.trim() || defaultTitle || "Published site";
|
|
54
|
+
return {
|
|
55
|
+
kind: "static_site",
|
|
56
|
+
rootDir,
|
|
57
|
+
title,
|
|
58
|
+
fileCount: files.length,
|
|
59
|
+
totalBytes,
|
|
60
|
+
assets,
|
|
61
|
+
manifest: {
|
|
62
|
+
schemaVersion: 1,
|
|
63
|
+
kind: "static_site",
|
|
64
|
+
title,
|
|
65
|
+
snapshotAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
66
|
+
...input.description?.trim() ? { description: input.description.trim() } : {},
|
|
67
|
+
entrypoint: "index.html",
|
|
68
|
+
spaFallback: input.spaFallback ?? true,
|
|
69
|
+
files
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
async function collectFiles(rootDir) {
|
|
75
|
+
const files = [];
|
|
76
|
+
const visit = async (directory) => {
|
|
77
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
78
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
79
|
+
for (const entry of entries) {
|
|
80
|
+
const absolutePath = resolve(directory, entry.name);
|
|
81
|
+
const details = await lstat(absolutePath);
|
|
82
|
+
if (details.isSymbolicLink()) throw new Error(`Static site cannot contain symbolic links: ${entry.name}`);
|
|
83
|
+
if (details.isDirectory()) {
|
|
84
|
+
await visit(absolutePath);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (!details.isFile()) throw new Error(`Unsupported static site entry: ${entry.name}`);
|
|
88
|
+
const filePath = relative(rootDir, absolutePath).split("\\").join("/");
|
|
89
|
+
if (filePath.split("/").some((part) => !part || part === "." || part === "..")) throw new Error("Invalid static site path");
|
|
90
|
+
files.push(posix.normalize(filePath));
|
|
91
|
+
if (files.length > MAX_FILES) throw new Error(`Static site has more than ${MAX_FILES} files`);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
await visit(rootDir);
|
|
95
|
+
return files;
|
|
96
|
+
}
|
|
97
|
+
function normalizeInputPath(value) {
|
|
98
|
+
const normalized = value.trim().replace(/\\/g, "/").replace(/^\/+/, "");
|
|
99
|
+
if (!normalized || normalized.includes("\0") || normalized.split("/").some((part) => part === "..")) throw new Error("Invalid static site path");
|
|
100
|
+
return normalized;
|
|
101
|
+
}
|
|
102
|
+
async function sha256File(filePath) {
|
|
103
|
+
const hash = createHash("sha256");
|
|
104
|
+
for await (const chunk of createReadStream(filePath)) hash.update(chunk);
|
|
105
|
+
return hash.digest("hex");
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { HostedStaticSitePublicationBuilder };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HostedPublicationPublisher, HostedShareBindingStore, type HostedShareBinding } from './hosted-session-share.js';
|
|
2
|
+
import { HostedStaticSitePublicationBuilder, type HostedStaticSitePublicationSnapshot } from './hosted-static-site-publication.js';
|
|
3
|
+
export interface PublishHostedStaticSiteInput {
|
|
4
|
+
workspaceRoot: string;
|
|
5
|
+
path: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
spaFallback?: boolean;
|
|
9
|
+
ttlMs: number;
|
|
10
|
+
maxViews: number | null;
|
|
11
|
+
sessionKey?: string;
|
|
12
|
+
agentId?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PublishHostedStaticSiteResult {
|
|
15
|
+
binding: HostedShareBinding;
|
|
16
|
+
snapshot: HostedStaticSitePublicationSnapshot;
|
|
17
|
+
}
|
|
18
|
+
/** Build, upload, activate, and locally bind one immutable static-site snapshot. */
|
|
19
|
+
export declare function publishHostedStaticSite(input: PublishHostedStaticSiteInput, deps?: {
|
|
20
|
+
builder?: HostedStaticSitePublicationBuilder;
|
|
21
|
+
publisher?: HostedPublicationPublisher;
|
|
22
|
+
bindings?: HostedShareBindingStore;
|
|
23
|
+
}): Promise<PublishHostedStaticSiteResult>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { HostedPublicationPublisher, HostedShareBindingStore } from "./hosted-session-share.js";
|
|
2
|
+
import { HostedStaticSitePublicationBuilder } from "./hosted-static-site-publication.js";
|
|
3
|
+
//#region src/share/hosted-static-site-publish.ts
|
|
4
|
+
/** Build, upload, activate, and locally bind one immutable static-site snapshot. */
|
|
5
|
+
async function publishHostedStaticSite(input, deps = {}) {
|
|
6
|
+
const builder = deps.builder ?? new HostedStaticSitePublicationBuilder();
|
|
7
|
+
const publisher = deps.publisher ?? new HostedPublicationPublisher();
|
|
8
|
+
const bindings = deps.bindings ?? new HostedShareBindingStore();
|
|
9
|
+
const snapshot = await builder.build(input.workspaceRoot, {
|
|
10
|
+
path: input.path,
|
|
11
|
+
title: input.title,
|
|
12
|
+
description: input.description,
|
|
13
|
+
spaFallback: input.spaFallback
|
|
14
|
+
});
|
|
15
|
+
const result = await publisher.createPublication(snapshot, {
|
|
16
|
+
ttlMs: input.ttlMs,
|
|
17
|
+
maxViews: input.maxViews
|
|
18
|
+
});
|
|
19
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20
|
+
const binding = {
|
|
21
|
+
...result,
|
|
22
|
+
kind: "static_site",
|
|
23
|
+
source: {
|
|
24
|
+
kind: "static_site",
|
|
25
|
+
id: input.path,
|
|
26
|
+
version: now
|
|
27
|
+
},
|
|
28
|
+
revisionSources: { [String(result.snapshotRevision)]: {
|
|
29
|
+
kind: "static_site",
|
|
30
|
+
id: input.path,
|
|
31
|
+
version: now
|
|
32
|
+
} },
|
|
33
|
+
workspaceContext: {
|
|
34
|
+
workspaceRoot: input.workspaceRoot,
|
|
35
|
+
...input.sessionKey ? { sessionKey: input.sessionKey } : {},
|
|
36
|
+
...input.agentId ? { agentId: input.agentId } : {}
|
|
37
|
+
},
|
|
38
|
+
title: snapshot.title,
|
|
39
|
+
description: input.description?.trim() || null,
|
|
40
|
+
attachmentCount: snapshot.fileCount,
|
|
41
|
+
attachmentIds: snapshot.assets.map((asset) => asset.id),
|
|
42
|
+
createdAt: now,
|
|
43
|
+
updatedAt: now,
|
|
44
|
+
revoked: false
|
|
45
|
+
};
|
|
46
|
+
await bindings.upsert(binding);
|
|
47
|
+
return {
|
|
48
|
+
binding,
|
|
49
|
+
snapshot
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { publishHostedStaticSite };
|
|
@@ -2,8 +2,8 @@ import { resolveStateDir } from "../config/paths-state.js";
|
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
4
|
import { init_paths } from "../config/paths.js";
|
|
5
|
-
import { collectReferencedAttachmentIds } from "../notes/note-attachment-sync.js";
|
|
6
5
|
import { issueShareAssetTicket, verifyShareAssetTicket } from "./share-asset-ticket.js";
|
|
6
|
+
import { collectReferencedAttachmentIds } from "../notes/note-attachment-sync.js";
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
8
8
|
import { createHash, randomUUID } from "node:crypto";
|
|
9
9
|
import { copyFile, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -155,7 +155,7 @@ var NoteShareService = class {
|
|
|
155
155
|
for (const id of referenced) if (!known.has(id)) throw new Error(`Referenced attachment is missing: ${id}`);
|
|
156
156
|
const selected = requestedAttachmentIds === void 0 ? [...referenced] : Array.from(new Set(requestedAttachmentIds));
|
|
157
157
|
for (const id of selected) if (!referenced.has(id)) throw new Error(`Attachment is not referenced by this Note: ${id}`);
|
|
158
|
-
const projectedMarkdown =
|
|
158
|
+
const projectedMarkdown = projectPublicNoteMarkdown(note, new Set(selected));
|
|
159
159
|
const markdownBytes = Buffer.byteLength(projectedMarkdown, "utf8");
|
|
160
160
|
if (markdownBytes > cfg.maxMarkdownBytes) throw new Error("Note Markdown exceeds sharing limit");
|
|
161
161
|
if (selected.length > cfg.maxAttachmentCount) throw new Error("Note has too many attachments to share");
|
|
@@ -235,7 +235,7 @@ var NoteShareService = class {
|
|
|
235
235
|
return join(resolveStateDir(), this.artifactRelativePath(shareId));
|
|
236
236
|
}
|
|
237
237
|
};
|
|
238
|
-
function
|
|
238
|
+
function projectPublicNoteMarkdown(note, selected) {
|
|
239
239
|
const canonicalTarget = "xopc-attachment://notes/([^/\\s)]+)/([^\\s)]+)";
|
|
240
240
|
const assertOwned = new RegExp(canonicalTarget, "gi");
|
|
241
241
|
note.markdown.replace(assertOwned, (_match, rawNoteId) => {
|
|
@@ -260,4 +260,4 @@ function projectPublicMarkdown(note, selected) {
|
|
|
260
260
|
return markdown;
|
|
261
261
|
}
|
|
262
262
|
//#endregion
|
|
263
|
-
export { NoteShareService, NoteShareVersionConflictError };
|
|
263
|
+
export { NoteShareService, NoteShareVersionConflictError, projectPublicNoteMarkdown };
|
|
@@ -33,7 +33,7 @@ export interface ResolvedSiteShareUrl {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Resolve the URL pair for a site share. Priority mirrors `resolveShareUrl`:
|
|
36
|
-
* 1. FRP tunnel →
|
|
36
|
+
* 1. FRP tunnel → gateway `/site/<token>/` subpath.
|
|
37
37
|
* 2. Reverse-proxy `publicUrl` → `<publicUrl>/site/<token>/` subpath.
|
|
38
38
|
* 3. Direct gateway bind → `http://<host>:<port>/site/<token>/`.
|
|
39
39
|
*/
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { enumerateLanGatewayCandidates } from "../gateway/host.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getTunnelService } from "../tunnel/tunnel-service.js";
|
|
3
3
|
//#region src/share/share-url.ts
|
|
4
4
|
function resolveShareUrl(token, ctx) {
|
|
5
|
-
const
|
|
5
|
+
const tunnelPublicUrl = activeTunnelPublicUrl();
|
|
6
6
|
const { gatewayHost, gatewayPort, reverseProxyPublicUrl } = ctx;
|
|
7
7
|
const path = `/s/${token}`;
|
|
8
|
-
if (
|
|
9
|
-
shareUrl: `${
|
|
8
|
+
if (tunnelPublicUrl) return {
|
|
9
|
+
shareUrl: `${tunnelPublicUrl.replace(/\/+$/, "")}${path}`,
|
|
10
10
|
lanUrl: buildLanUrl(gatewayHost, gatewayPort, path),
|
|
11
11
|
reachability: "public",
|
|
12
12
|
reachabilityHint: null
|
|
@@ -40,22 +40,23 @@ function isLoopbackHost(host) {
|
|
|
40
40
|
return host === "127.0.0.1" || host === "localhost" || host === "::1";
|
|
41
41
|
}
|
|
42
42
|
function resolveReachabilityForList(ctx) {
|
|
43
|
-
if (
|
|
43
|
+
if (activeTunnelPublicUrl()) return "public";
|
|
44
44
|
if (ctx.reverseProxyPublicUrl?.trim()) return "public";
|
|
45
45
|
if (!isLoopbackHost(ctx.gatewayHost)) return "lan";
|
|
46
46
|
return "local-only";
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Resolve the URL pair for a site share. Priority mirrors `resolveShareUrl`:
|
|
50
|
-
* 1. FRP tunnel →
|
|
50
|
+
* 1. FRP tunnel → gateway `/site/<token>/` subpath.
|
|
51
51
|
* 2. Reverse-proxy `publicUrl` → `<publicUrl>/site/<token>/` subpath.
|
|
52
52
|
* 3. Direct gateway bind → `http://<host>:<port>/site/<token>/`.
|
|
53
53
|
*/
|
|
54
54
|
function resolveSiteShareUrl(ctx) {
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const tunnelPublicUrl = activeTunnelPublicUrl();
|
|
56
|
+
if (tunnelPublicUrl) {
|
|
57
|
+
const root = tunnelPublicUrl.replace(/\/+$/, "");
|
|
57
58
|
return {
|
|
58
|
-
shareUrl: `${root}/`,
|
|
59
|
+
shareUrl: `${root}/site/${ctx.token}/`,
|
|
59
60
|
thumbnailUrl: `${root}/site/${ctx.token}/thumbnail`,
|
|
60
61
|
reachability: "public",
|
|
61
62
|
reachabilityHint: null
|
|
@@ -80,5 +81,9 @@ function resolveSiteShareUrl(ctx) {
|
|
|
80
81
|
reachabilityHint: loopback ? "当前仅本机可访问,开启远程隧道后对外可达" : "当前局域网内可访问,开启远程隧道后对外网可达"
|
|
81
82
|
};
|
|
82
83
|
}
|
|
84
|
+
function activeTunnelPublicUrl() {
|
|
85
|
+
const status = getTunnelService().getStatus();
|
|
86
|
+
return status.state === "connected" && status.publicUrl ? status.publicUrl : null;
|
|
87
|
+
}
|
|
83
88
|
//#endregion
|
|
84
89
|
export { resolveReachabilityForList, resolveShareUrl, resolveSiteShareUrl };
|
|
@@ -2,10 +2,10 @@ import { isHomeAttentionAcknowledged } from "../storage/sqlite/home-attention-re
|
|
|
2
2
|
import { getRelationshipSettings } from "../storage/sqlite/relationship-settings-repository.js";
|
|
3
3
|
import { listConnectorApprovals } from "../storage/sqlite/connector-repository.js";
|
|
4
4
|
import "../storage/sqlite/index.js";
|
|
5
|
-
import { TaskRepository } from "./task-repository.js";
|
|
6
|
-
import { TaskReadModelProjector } from "./task-read-model-projector.js";
|
|
7
5
|
import "../automations/domain/defaults.js";
|
|
8
6
|
import "../automations/index.js";
|
|
7
|
+
import { TaskRepository } from "./task-repository.js";
|
|
8
|
+
import { TaskReadModelProjector } from "./task-read-model-projector.js";
|
|
9
9
|
import { AttentionGovernor } from "./attention-governor.js";
|
|
10
10
|
import { listGatewayAgents } from "../gateway/agents-admin.js";
|
|
11
11
|
//#region src/tasks/home-query-service.ts
|
|
@@ -12,11 +12,11 @@ import { effectiveWorkspacePathForSession } from "../../session/session-workspac
|
|
|
12
12
|
import { ProjectService } from "../../projects/project-service.js";
|
|
13
13
|
import { inferSuggestedProjectDefaultAgentId } from "../../projects/project-agent-suggestion.js";
|
|
14
14
|
import "../../projects/index.js";
|
|
15
|
+
import { buildSessionTimeline } from "../../session/transcript-outline.js";
|
|
16
|
+
import { transcriptRowsToClientHistory } from "../../session/client-history.js";
|
|
15
17
|
import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
|
|
16
18
|
import { evictEmbeddedSessionRunner } from "../../agent/embedded/session-runner.js";
|
|
17
19
|
import { setTuiDefaultAgentConfig } from "../../commands/agents.config.js";
|
|
18
|
-
import { buildSessionTimeline } from "../../session/transcript-outline.js";
|
|
19
|
-
import { transcriptRowsToClientHistory } from "../../session/client-history.js";
|
|
20
20
|
import { SessionIndex } from "../../session/manager.js";
|
|
21
21
|
import "../../session/index.js";
|
|
22
22
|
import { parseModelRef } from "../../agent/models/selection.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatAgentRunErrorForDisplay } from "../agent/client-error-format.js";
|
|
2
1
|
import { stripRuntimeContextFromUserContent } from "../session/user-message-display.js";
|
|
2
|
+
import { formatAgentRunErrorForDisplay } from "../agent/client-error-format.js";
|
|
3
3
|
import { createAssistantMessageFromText } from "./components/assistant-message.js";
|
|
4
4
|
import { markRunEvent, markRunIdleAfterCompletion } from "./tui-run-state.js";
|
|
5
5
|
//#region src/tui/tui-agent-events.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
3
2
|
import { init_paths, resolveAgentProfileDir, resolveBundledSkillsDir } from "../config/paths.js";
|
|
3
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
4
4
|
import { resolveBootstrapFilesSync } from "../agent/bootstrap/bootstrap-files.js";
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "../agent/skills/config.js";
|
|
6
6
|
import { loadSkills } from "../agent/skills/index.js";
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -2,10 +2,10 @@ import { version } from "../../package.js";
|
|
|
2
2
|
import { resolveStateDir, resolveXopcDatabasePath } from "../config/paths-state.js";
|
|
3
3
|
import { parseAgentSessionKey } from "../routing/session-key-utils.js";
|
|
4
4
|
import { init_agent_session_key, normalizeAgentId } from "../routing/agent-session-key.js";
|
|
5
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
6
5
|
import { init_paths } from "../config/paths.js";
|
|
7
6
|
import { loadConfig } from "../config/loader.js";
|
|
8
7
|
import { getAllModels, getAllProviders, getApiKey, init_providers, isProviderConfiguredSync } from "../providers/index.js";
|
|
8
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
9
9
|
import { ProjectTrustStore, hasTrustRequiringProjectResources } from "../project-trust/trust-store.js";
|
|
10
10
|
import { renderWorkflowFinalSummary, renderWorkflowPanel } from "../agent/workflow/snapshot.js";
|
|
11
11
|
import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
|
package/dist/src/tunnel/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { loadTunnelState, resolveTunnelStatePath, saveTunnelState } from "./tunnel-state.js";
|
|
2
1
|
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
3
2
|
import { FRPC_VERSION, clearFrpcPathForProcess, ensureFrpcBinary, publishFrpcPathForProcess } from "./frpc-binary.js";
|
|
4
3
|
import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, isLocalDevelopmentTunnelBroker, isMaskedTunnelSecretPatchValue, resolveOptionalTunnelRegistrationSecret, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret, tunnelRegistrationSecretRequiredMessage } from "./env.js";
|
|
4
|
+
import { loadTunnelState, resolveTunnelStatePath, saveTunnelState } from "./tunnel-state.js";
|
|
5
5
|
import { logTunnelAudit } from "./tunnel-audit.js";
|
|
6
6
|
import { TunnelService, getTunnelService, hashGatewayToken } from "./tunnel-service.js";
|
|
7
7
|
import { CURRENT_TUNNEL_CONSENT_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState, hasValidTunnelConsent } from "./consent.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import { clearTunnelState, loadTunnelState, saveTunnelState, updateTunnelState } from "./tunnel-state.js";
|
|
5
4
|
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
6
5
|
import { clearFrpcPathForProcess, ensureFrpcBinary, publishFrpcPathForProcess } from "./frpc-binary.js";
|
|
7
6
|
import { writeFrpcConfig } from "./frpc-config.js";
|
|
8
7
|
import { spawnFrpcProcess } from "./frpc-process.js";
|
|
9
8
|
import { TunnelRegistrationSecretError } from "./env.js";
|
|
10
9
|
import { canResumePersistedTunnel, persistedFromRegistration, registrationFromPersisted } from "./tunnel-persist.js";
|
|
10
|
+
import { clearTunnelState, loadTunnelState, saveTunnelState, updateTunnelState } from "./tunnel-state.js";
|
|
11
11
|
import { logTunnelAudit } from "./tunnel-audit.js";
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
import { EventEmitter } from "node:events";
|
|
@@ -3,6 +3,7 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { speakStream } from "../tts/speak-core.js";
|
|
4
4
|
import { AudioPlaybackWindow } from "./audio-playback-window.js";
|
|
5
5
|
import { ConversationTurn } from "./conversationTurn.js";
|
|
6
|
+
import { isLikelyPlaybackEcho } from "./playback-echo.js";
|
|
6
7
|
import { SpeakableSegmenter } from "./speakable-segmenter.js";
|
|
7
8
|
import crypto from "node:crypto";
|
|
8
9
|
//#region src/voice/realtime/agentEngine.ts
|
|
@@ -89,6 +90,7 @@ function createAgentVoiceEngine(options) {
|
|
|
89
90
|
signal: response.abortController.signal,
|
|
90
91
|
allowFallback: false
|
|
91
92
|
});
|
|
93
|
+
let phraseMarkedAudible = false;
|
|
92
94
|
try {
|
|
93
95
|
if (response.abortController.signal.aborted || activeResponse !== response || closed) return;
|
|
94
96
|
if (result.outputFormat !== "pcm") throw new Error(`Realtime TTS returned unsupported format: ${result.outputFormat}`);
|
|
@@ -97,6 +99,10 @@ function createAgentVoiceEngine(options) {
|
|
|
97
99
|
const item = await reader.read();
|
|
98
100
|
if (item.done) break;
|
|
99
101
|
if (response.abortController.signal.aborted || activeResponse !== response) return;
|
|
102
|
+
if (!phraseMarkedAudible && item.value.byteLength > 0) {
|
|
103
|
+
phraseMarkedAudible = true;
|
|
104
|
+
response.audibleText = `${response.audibleText} ${phrase}`.trim().slice(-8e3);
|
|
105
|
+
}
|
|
100
106
|
if (!response.audioStarted) {
|
|
101
107
|
response.audioStarted = true;
|
|
102
108
|
log.info({
|
|
@@ -153,6 +159,7 @@ function createAgentVoiceEngine(options) {
|
|
|
153
159
|
abortController: new AbortController(),
|
|
154
160
|
segmenter: new SpeakableSegmenter(),
|
|
155
161
|
text: "",
|
|
162
|
+
audibleText: "",
|
|
156
163
|
audioStarted: false,
|
|
157
164
|
speechTail: Promise.resolve(),
|
|
158
165
|
queuedSpeechCharacters: 0,
|
|
@@ -185,6 +192,7 @@ function createAgentVoiceEngine(options) {
|
|
|
185
192
|
});
|
|
186
193
|
queuePhrases(response, response.segmenter.push(event.payload.delta));
|
|
187
194
|
}
|
|
195
|
+
if (event.type === "tool_start") queuePhrases(response, response.segmenter.flush());
|
|
188
196
|
if ((event.type === "tool_start" || event.type === "tool_end") && typeof event.payload?.toolCallId === "string" && typeof event.payload?.toolName === "string") send("response.activity", {
|
|
189
197
|
responseId: response.id,
|
|
190
198
|
toolCallId: event.payload.toolCallId.slice(0, 160),
|
|
@@ -333,6 +341,15 @@ function createAgentVoiceEngine(options) {
|
|
|
333
341
|
}
|
|
334
342
|
finalizedUtterances.add(event.utteranceId);
|
|
335
343
|
finalCount += 1;
|
|
344
|
+
if (claim.request.purpose === "conversation" && activeResponse?.audioStarted && isLikelyPlaybackEcho(text, activeResponse.audibleText)) {
|
|
345
|
+
bufferFinal(event.utteranceId, "");
|
|
346
|
+
log.debug({
|
|
347
|
+
sessionId: claim.sessionId,
|
|
348
|
+
responseId: activeResponse.id,
|
|
349
|
+
transcriptCharacters: text.length
|
|
350
|
+
}, "Ignored finalized transcription matching active voice playback");
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
336
353
|
send("input.transcript.final", {
|
|
337
354
|
utteranceId: event.utteranceId,
|
|
338
355
|
revision: event.revision,
|
|
@@ -8,8 +8,8 @@ import { getKnowledgeItem } from "../../knowledge-memory/repository.js";
|
|
|
8
8
|
import "../../knowledge-memory/index.js";
|
|
9
9
|
import { getUserAssertion } from "../../user-model/repository.js";
|
|
10
10
|
import "../../user-model/index.js";
|
|
11
|
-
import { buildExecutionContext } from "../../agent/context/execution-context.js";
|
|
12
11
|
import { stripRuntimeContextFromUserMessage } from "../../session/user-message-display.js";
|
|
12
|
+
import { buildExecutionContext } from "../../agent/context/execution-context.js";
|
|
13
13
|
//#region src/voice/realtime/memory-context.ts
|
|
14
14
|
init_session_key();
|
|
15
15
|
init_logger();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/voice/realtime/playback-echo.ts
|
|
2
|
+
function normalizeSpeech(text) {
|
|
3
|
+
return text.toLocaleLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}]/gu, "");
|
|
4
|
+
}
|
|
5
|
+
/** Conservatively identifies finalized ASR that is already in audible assistant output. */
|
|
6
|
+
function isLikelyPlaybackEcho(transcript, assistantText) {
|
|
7
|
+
const heard = normalizeSpeech(transcript);
|
|
8
|
+
const spoken = normalizeSpeech(assistantText);
|
|
9
|
+
if (!heard || !spoken) return false;
|
|
10
|
+
const containsCjk = /\p{Script=Han}/u.test(heard);
|
|
11
|
+
if (heard.length < (containsCjk ? 3 : 6)) return false;
|
|
12
|
+
return spoken.includes(heard);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { isLikelyPlaybackEcho };
|
|
@@ -6,12 +6,12 @@ import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
|
6
6
|
import { buildSessionKey, init_session_key } from "../routing/session-key.js";
|
|
7
7
|
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
8
8
|
import { init_providers, resolveModel } from "../providers/index.js";
|
|
9
|
+
import { isLocalModelBaseUrl } from "../providers/model-call.js";
|
|
9
10
|
import { writeKnowledgeItem } from "../knowledge-memory/repository.js";
|
|
10
11
|
import "../knowledge-memory/index.js";
|
|
11
12
|
import { createPriorityWindow, createUserGoal } from "../user-model/goals.js";
|
|
12
13
|
import { getAssertionSlot, getUserAssertion, linkAssertionEvidence, reconcileAssertion, setAssertionStatus } from "../user-model/repository.js";
|
|
13
14
|
import "../user-model/index.js";
|
|
14
|
-
import { isLocalModelBaseUrl } from "../providers/model-call.js";
|
|
15
15
|
import { allowsRemoteSourceProcessing } from "../user-context/sources/processing-policy.js";
|
|
16
16
|
import { analyzeUnderstandingSources, analyzeWorkContext, workDiscoveryResultMarkdown } from "./analyzer.js";
|
|
17
17
|
import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceGrantPolicies, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { TaskRunRepository } from "../../tasks/task-run-repository.js";
|
|
2
2
|
import { getDefaultAgentId, init_resolve_route } from "../../routing/resolve-route.js";
|
|
3
|
-
import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
4
3
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
|
+
import { publishAutomationProductEvent } from "../../automations/product-events.js";
|
|
5
|
+
import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
5
6
|
import { TaskRepository } from "../../tasks/task-repository.js";
|
|
6
7
|
import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
|
|
7
8
|
import { getProjectWorkspacePathForSession } from "../../projects/workspace.js";
|
|
8
|
-
import { publishAutomationProductEvent } from "../../automations/product-events.js";
|
|
9
9
|
import { TaskContextRepository } from "../../tasks/task-context-repository.js";
|
|
10
10
|
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
11
11
|
import { resolveModelSelector } from "../../config/agent-model-intents.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.255",
|
|
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",
|
|
@@ -162,10 +162,10 @@
|
|
|
162
162
|
"vitepress": "^1.6.4",
|
|
163
163
|
"vitest": "4.1.5",
|
|
164
164
|
"vue": "^3.5.35",
|
|
165
|
-
"@xopcai/browser-control-contract": "0.1.0",
|
|
166
165
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
167
166
|
"@xopcai/realtime-client": "0.0.0",
|
|
168
167
|
"@xopcai/gateway-contract": "0.0.0",
|
|
168
|
+
"@xopcai/browser-control-contract": "0.1.0",
|
|
169
169
|
"@xopcai/realtime-protocol": "0.0.0"
|
|
170
170
|
},
|
|
171
171
|
"scripts": {
|