@antelopejs/dms-ai 0.1.2 → 0.1.3
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 +49 -0
- package/dist/channels/bridge.d.ts +22 -0
- package/dist/channels/bridge.js +87 -0
- package/dist/channels/bridge.js.map +1 -0
- package/dist/channels/channel-service.d.ts +5 -0
- package/dist/channels/channel-service.js +68 -0
- package/dist/channels/channel-service.js.map +1 -0
- package/dist/channels/message-budget.d.ts +3 -0
- package/dist/channels/message-budget.js +29 -0
- package/dist/channels/message-budget.js.map +1 -0
- package/dist/channels/registry.d.ts +7 -0
- package/dist/channels/registry.js +47 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/sse-stream.d.ts +19 -0
- package/dist/channels/sse-stream.js +59 -0
- package/dist/channels/sse-stream.js.map +1 -0
- package/dist/chatbox/passthrough.d.ts +3 -0
- package/dist/chatbox/passthrough.js +53 -0
- package/dist/chatbox/passthrough.js.map +1 -0
- package/dist/constants/channels.d.ts +30 -0
- package/dist/constants/channels.js +38 -0
- package/dist/constants/channels.js.map +1 -0
- package/dist/constants/chatbox.d.ts +10 -0
- package/dist/constants/chatbox.js +35 -0
- package/dist/constants/chatbox.js.map +1 -0
- package/dist/constants/sidecar.d.ts +4 -0
- package/dist/constants/sidecar.js +3 -1
- package/dist/constants/sidecar.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/sidecar-socket.d.ts +2 -0
- package/dist/lifecycle/sidecar-socket.js +37 -0
- package/dist/lifecycle/sidecar-socket.js.map +1 -0
- package/dist/lifecycle/sidecar-unavailable-error.d.ts +3 -0
- package/dist/lifecycle/sidecar-unavailable-error.js +10 -0
- package/dist/lifecycle/sidecar-unavailable-error.js.map +1 -0
- package/dist/routes/channels.d.ts +8 -0
- package/dist/routes/channels.js +52 -0
- package/dist/routes/channels.js.map +1 -0
- package/dist/routes/chatbox.d.ts +7 -0
- package/dist/routes/chatbox.js +47 -0
- package/dist/routes/chatbox.js.map +1 -0
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.js +2 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/sidecar-info.js +0 -2
- package/dist/routes/sidecar-info.js.map +1 -1
- package/frontend-vue/app/components/SettingsView.vue +8 -0
- package/frontend-vue/app/plugins/ai.client.ts +137 -58
- package/frontend-vue/app/runtime/channel-client.ts +265 -0
- package/frontend-vue/app/runtime/chat-transport.ts +82 -0
- package/frontend-vue/app/runtime/constants.ts +30 -14
- package/frontend-vue/app/runtime/current-page.ts +9 -5
- package/frontend-vue/app/runtime/event-stream.ts +75 -0
- package/frontend-vue/app/runtime/overlay.ts +23 -6
- package/frontend-vue/app/runtime/sidecar-status.ts +10 -25
- package/frontend-vue/app/runtime/theme-bridge.ts +16 -4
- package/frontend-vue/package.json +3 -0
- package/frontend-vue/tests/backoff.test.ts +15 -15
- package/frontend-vue/tests/channel-client.test.ts +247 -0
- package/frontend-vue/tests/chat-transport.test.ts +67 -0
- package/frontend-vue/tests/sidecar-status.test.ts +39 -0
- package/package.json +5 -3
- package/sidecar/chatbox/dist/assets/index-C8u7mkHn.css +1 -0
- package/sidecar/chatbox/dist/assets/index-tdZvY7ee.js +52 -0
- package/sidecar/chatbox/dist/index.html +2 -2
- package/sidecar/dist/agent/disposals.d.ts +5 -0
- package/sidecar/dist/agent/disposals.js +17 -0
- package/sidecar/dist/agent/disposals.js.map +1 -0
- package/sidecar/dist/agent/effective-mode.d.ts +2 -0
- package/sidecar/dist/agent/effective-mode.js +20 -0
- package/sidecar/dist/agent/effective-mode.js.map +1 -0
- package/sidecar/dist/agent/provider.d.ts +2 -2
- package/sidecar/dist/agent/runner-events.d.ts +9 -1
- package/sidecar/dist/agent/runner.d.ts +2 -2
- package/sidecar/dist/agent/runner.js +11 -5
- package/sidecar/dist/agent/runner.js.map +1 -1
- package/sidecar/dist/agent/session.d.ts +3 -3
- package/sidecar/dist/agent/session.js +54 -34
- package/sidecar/dist/agent/session.js.map +1 -1
- package/sidecar/dist/agent/switching-runner.js +16 -14
- package/sidecar/dist/agent/switching-runner.js.map +1 -1
- package/sidecar/dist/agent/turn-end-reasons.d.ts +3 -0
- package/sidecar/dist/agent/turn-end-reasons.js +24 -0
- package/sidecar/dist/agent/turn-end-reasons.js.map +1 -0
- package/sidecar/dist/constants/agent.d.ts +6 -1
- package/sidecar/dist/constants/agent.js +13 -1
- package/sidecar/dist/constants/agent.js.map +1 -1
- package/sidecar/dist/constants/claude.d.ts +27 -1
- package/sidecar/dist/constants/claude.js +49 -0
- package/sidecar/dist/constants/claude.js.map +1 -1
- package/sidecar/dist/constants/codex.d.ts +6 -0
- package/sidecar/dist/constants/codex.js +13 -0
- package/sidecar/dist/constants/codex.js.map +1 -1
- package/sidecar/dist/constants/settings.js.map +1 -1
- package/sidecar/dist/constants/timing.d.ts +1 -0
- package/sidecar/dist/constants/timing.js +1 -0
- package/sidecar/dist/constants/timing.js.map +1 -1
- package/sidecar/dist/protocol/events.d.ts +36 -0
- package/sidecar/dist/protocol/events.js +13 -0
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/providers/claude/activity.d.ts +5 -0
- package/sidecar/dist/providers/claude/activity.js +63 -0
- package/sidecar/dist/providers/claude/activity.js.map +1 -0
- package/sidecar/dist/providers/claude/adapter.js +21 -13
- package/sidecar/dist/providers/claude/adapter.js.map +1 -1
- package/sidecar/dist/providers/claude/config.d.ts +2 -1
- package/sidecar/dist/providers/claude/config.js +4 -0
- package/sidecar/dist/providers/claude/config.js.map +1 -1
- package/sidecar/dist/providers/claude/provider.js +18 -25
- package/sidecar/dist/providers/claude/provider.js.map +1 -1
- package/sidecar/dist/providers/claude/result.d.ts +3 -0
- package/sidecar/dist/providers/claude/result.js +61 -0
- package/sidecar/dist/providers/claude/result.js.map +1 -0
- package/sidecar/dist/providers/claude/safe-mode.d.ts +4 -0
- package/sidecar/dist/providers/claude/safe-mode.js +24 -0
- package/sidecar/dist/providers/claude/safe-mode.js.map +1 -0
- package/sidecar/dist/providers/codex/adapter.js +8 -2
- package/sidecar/dist/providers/codex/adapter.js.map +1 -1
- package/sidecar/dist/providers/codex/client.d.ts +1 -0
- package/sidecar/dist/providers/codex/client.js +1 -0
- package/sidecar/dist/providers/codex/client.js.map +1 -1
- package/sidecar/dist/providers/codex/config.js +2 -1
- package/sidecar/dist/providers/codex/config.js.map +1 -1
- package/sidecar/dist/providers/codex/process.js +113 -33
- package/sidecar/dist/providers/codex/process.js.map +1 -1
- package/sidecar/dist/providers/codex/provider.js +6 -4
- package/sidecar/dist/providers/codex/provider.js.map +1 -1
- package/sidecar/dist/server/routing.js +39 -21
- package/sidecar/dist/server/routing.js.map +1 -1
- package/sidecar/dist/server/turn-progress.d.ts +13 -0
- package/sidecar/dist/server/turn-progress.js +72 -0
- package/sidecar/dist/server/turn-progress.js.map +1 -0
- package/sidecar/dist/server/ws.js +4 -2
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/state/types.d.ts +2 -1
- package/sidecar/dist/state/types.js +1 -0
- package/sidecar/dist/state/types.js.map +1 -1
- package/sidecar/package.json +1 -1
- package/frontend-vue/app/runtime/ws-client.ts +0 -196
- package/frontend-vue/tests/sidecar-auth.test.ts +0 -87
- package/sidecar/chatbox/dist/assets/index-CEZ1NLp9.js +0 -52
- package/sidecar/chatbox/dist/assets/index-D_51Vqqk.css +0 -1
|
@@ -24,3 +24,7 @@ export declare const MODULE_ROOTS_TIMEOUT_MS = 3000;
|
|
|
24
24
|
export declare const SIDECAR_DIST_EXTENSION = ".js";
|
|
25
25
|
export declare const SIDECAR_LOOPBACK_HOST = "127.0.0.1";
|
|
26
26
|
export declare const SIDECAR_AUTH_HEADER = "x-dms-ai-token";
|
|
27
|
+
export declare const SIDECAR_UNAVAILABLE_STATUS = 503;
|
|
28
|
+
export declare const SIDECAR_UNAVAILABLE_BODY: {
|
|
29
|
+
error: string;
|
|
30
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SIDECAR_AUTH_HEADER = exports.SIDECAR_LOOPBACK_HOST = exports.SIDECAR_DIST_EXTENSION = exports.MODULE_ROOTS_TIMEOUT_MS = exports.SIDECAR_HOST_ORIGIN_FLAG = exports.SIDECAR_BACKEND_URL_FLAG = exports.SIDECAR_BUILDER_FLAG = exports.SIDECAR_SKILL_DIRS_FLAG = exports.SIDECAR_MODULE_ROOTS_FLAG = exports.SIDECAR_BUILD_ID_FLAG = exports.SIDECAR_LOCK_POLL_INTERVAL_MS = exports.SIDECAR_HEALTH_TIMEOUT_MS = exports.SIDECAR_HEALTH_PATH = exports.SIDECAR_LOG_FILE_NAME = exports.SIDECAR_LOCK_FILE_NAME = exports.SIDECAR_CACHE_DIR_SEGMENTS = exports.SIDECAR_SUCCESS_EXIT_CODE = exports.SIDECAR_DIST_REL = exports.SIDECAR_ENV_DISABLE_KEY = exports.SIDECAR_DISABLED_FLAG = exports.SIDECAR_LOG_PREFIX = exports.SIDECAR_RESPAWN_DELAY_MS = exports.SIDECAR_RESPAWN_WINDOW_MS = exports.SIDECAR_RESPAWN_MAX = exports.SIDECAR_SPAWN_TIMEOUT_MS = exports.SIDECAR_BIN_NAME = void 0;
|
|
3
|
+
exports.SIDECAR_UNAVAILABLE_BODY = exports.SIDECAR_UNAVAILABLE_STATUS = exports.SIDECAR_AUTH_HEADER = exports.SIDECAR_LOOPBACK_HOST = exports.SIDECAR_DIST_EXTENSION = exports.MODULE_ROOTS_TIMEOUT_MS = exports.SIDECAR_HOST_ORIGIN_FLAG = exports.SIDECAR_BACKEND_URL_FLAG = exports.SIDECAR_BUILDER_FLAG = exports.SIDECAR_SKILL_DIRS_FLAG = exports.SIDECAR_MODULE_ROOTS_FLAG = exports.SIDECAR_BUILD_ID_FLAG = exports.SIDECAR_LOCK_POLL_INTERVAL_MS = exports.SIDECAR_HEALTH_TIMEOUT_MS = exports.SIDECAR_HEALTH_PATH = exports.SIDECAR_LOG_FILE_NAME = exports.SIDECAR_LOCK_FILE_NAME = exports.SIDECAR_CACHE_DIR_SEGMENTS = exports.SIDECAR_SUCCESS_EXIT_CODE = exports.SIDECAR_DIST_REL = exports.SIDECAR_ENV_DISABLE_KEY = exports.SIDECAR_DISABLED_FLAG = exports.SIDECAR_LOG_PREFIX = exports.SIDECAR_RESPAWN_DELAY_MS = exports.SIDECAR_RESPAWN_WINDOW_MS = exports.SIDECAR_RESPAWN_MAX = exports.SIDECAR_SPAWN_TIMEOUT_MS = exports.SIDECAR_BIN_NAME = void 0;
|
|
4
4
|
exports.SIDECAR_BIN_NAME = "dms-ai-sidecar";
|
|
5
5
|
exports.SIDECAR_SPAWN_TIMEOUT_MS = 10_000;
|
|
6
6
|
exports.SIDECAR_RESPAWN_MAX = 3;
|
|
@@ -31,4 +31,6 @@ exports.MODULE_ROOTS_TIMEOUT_MS = 3_000;
|
|
|
31
31
|
exports.SIDECAR_DIST_EXTENSION = ".js";
|
|
32
32
|
exports.SIDECAR_LOOPBACK_HOST = "127.0.0.1";
|
|
33
33
|
exports.SIDECAR_AUTH_HEADER = "x-dms-ai-token";
|
|
34
|
+
exports.SIDECAR_UNAVAILABLE_STATUS = 503;
|
|
35
|
+
exports.SIDECAR_UNAVAILABLE_BODY = { error: "sidecar_unavailable" };
|
|
34
36
|
//# sourceMappingURL=sidecar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/constants/sidecar.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,gBAAgB,CAAC;AACpC,QAAA,wBAAwB,GAAG,MAAM,CAAC;AAClC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,wBAAwB,GAAG,GAAG,CAAC;AAC/B,QAAA,kBAAkB,GAAG,UAAU,CAAC;AAChC,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAC5B,QAAA,uBAAuB,GAAG,QAAQ,CAAC;AACnC,QAAA,gBAAgB,GAAG,6BAA6B,CAAC;AACjD,QAAA,yBAAyB,GAAG,CAAC,CAAC;AAC9B,QAAA,0BAA0B,GAAG;IACxC,cAAc;IACd,QAAQ;IACR,QAAQ;CACA,CAAC;AACE,QAAA,sBAAsB,GAAG,cAAc,CAAC;AACxC,QAAA,qBAAqB,GAAG,aAAa,CAAC;AACtC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,yBAAyB,GAAG,IAAI,CAAC;AACjC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACpC,QAAA,qBAAqB,GAAG,YAAY,CAAC;AACrC,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAC7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AACzC,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAChC,QAAA,sBAAsB,GAAG,KAAK,CAAC;AAC/B,QAAA,qBAAqB,GAAG,WAAW,CAAC;AACpC,QAAA,mBAAmB,GAAG,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/constants/sidecar.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,gBAAgB,CAAC;AACpC,QAAA,wBAAwB,GAAG,MAAM,CAAC;AAClC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,wBAAwB,GAAG,GAAG,CAAC;AAC/B,QAAA,kBAAkB,GAAG,UAAU,CAAC;AAChC,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAC5B,QAAA,uBAAuB,GAAG,QAAQ,CAAC;AACnC,QAAA,gBAAgB,GAAG,6BAA6B,CAAC;AACjD,QAAA,yBAAyB,GAAG,CAAC,CAAC;AAC9B,QAAA,0BAA0B,GAAG;IACxC,cAAc;IACd,QAAQ;IACR,QAAQ;CACA,CAAC;AACE,QAAA,sBAAsB,GAAG,cAAc,CAAC;AACxC,QAAA,qBAAqB,GAAG,aAAa,CAAC;AACtC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,yBAAyB,GAAG,IAAI,CAAC;AACjC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACpC,QAAA,qBAAqB,GAAG,YAAY,CAAC;AACrC,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAC7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AACzC,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAChC,QAAA,sBAAsB,GAAG,KAAK,CAAC;AAC/B,QAAA,qBAAqB,GAAG,WAAW,CAAC;AACpC,QAAA,mBAAmB,GAAG,gBAAgB,CAAC;AAGvC,QAAA,0BAA0B,GAAG,GAAG,CAAC;AACjC,QAAA,wBAAwB,GAAG,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -5,10 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.construct = construct;
|
|
7
7
|
exports.start = start;
|
|
8
|
+
exports.destroy = destroy;
|
|
8
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
10
|
const logging_1 = require("@antelopejs/interface-core/logging");
|
|
10
11
|
const page_1 = require("@antelopejs/interface-dms/page");
|
|
11
12
|
const presence_1 = require("./builder/presence");
|
|
13
|
+
const registry_1 = require("./channels/registry");
|
|
12
14
|
const config_1 = require("./config");
|
|
13
15
|
const frontend_module_1 = require("./constants/frontend-module");
|
|
14
16
|
const sidecar_1 = require("./constants/sidecar");
|
|
@@ -44,4 +46,7 @@ async function start() {
|
|
|
44
46
|
logging_1.Logging.Error(`${sidecar_1.SIDECAR_LOG_PREFIX} spawn failed:`, err);
|
|
45
47
|
});
|
|
46
48
|
}
|
|
49
|
+
function destroy() {
|
|
50
|
+
(0, registry_1.closeAllBridges)();
|
|
51
|
+
}
|
|
47
52
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAmBA,8BAEC;AAED,sBAyBC;AAOD,0BAEC;AAzDD,0DAA6B;AAC7B,gEAA6D;AAC7D,yDAAmE;AACnE,iDAAwD;AACxD,kDAAsD;AACtD,qCAA6D;AAC7D,iEAIqC;AACrC,iDAAyD;AACzD,2DAA8D;AAC9D,6DAAgE;AAChE,6DAAyD;AACzD,qDAAuD;AACvD,mBAAiB;AACjB,oBAAkB;AAElB,SAAgB,SAAS,CAAC,MAAe;IACvC,IAAA,kBAAS,EAAC,IAAA,oBAAW,EAAC,MAAM,CAAC,CAAC,CAAC;AACjC,CAAC;AAEM,KAAK,UAAU,KAAK;IACzB,IAAA,4BAAe,GAAE,CAAC;IAClB,MAAM,IAAA,wBAAiB,EAAC;QACtB,IAAI,EAAE,sCAAoB;QAC1B,UAAU,EAAE,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qCAAmB,CAAC;QACrD,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE;QACvC,QAAQ,EAAE,0CAAwB;KACnC,CAAC,CAAC;IAIH,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjE,IAAA,iCAAkB,GAAE;QACpB,IAAA,mCAAmB,GAAE;QACrB,IAAA,6BAAkB,GAAE;KACrB,CAAC,CAAC;IACH,KAAK,IAAA,4BAAY,EAAC;QAChB,eAAe,EAAE,OAAO,CAAC,GAAG,EAAE;QAC9B,GAAG,IAAA,kBAAS,GAAE;QACd,WAAW;QACX,SAAS;QACT,cAAc;KACf,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,iBAAO,CAAC,KAAK,CAAC,GAAG,4BAAkB,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAOD,SAAgB,OAAO;IACrB,IAAA,0BAAe,GAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.connectSidecarSocket = connectSidecarSocket;
|
|
7
|
+
const ws_1 = __importDefault(require("ws"));
|
|
8
|
+
const channels_1 = require("../constants/channels");
|
|
9
|
+
const sidecar_1 = require("../constants/sidecar");
|
|
10
|
+
const spawn_sidecar_1 = require("./spawn-sidecar");
|
|
11
|
+
const sidecar_unavailable_error_1 = require("./sidecar-unavailable-error");
|
|
12
|
+
const HANDSHAKE_TIMEOUT_MS = 5_000;
|
|
13
|
+
function openSocket(url, token) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const socket = new ws_1.default(url, {
|
|
16
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
17
|
+
maxPayload: channels_1.CHANNEL_MESSAGE_MAX_BYTES,
|
|
18
|
+
handshakeTimeout: HANDSHAKE_TIMEOUT_MS,
|
|
19
|
+
});
|
|
20
|
+
const onError = () => reject(new sidecar_unavailable_error_1.SidecarUnavailableError());
|
|
21
|
+
socket.once("error", onError);
|
|
22
|
+
socket.once("open", () => {
|
|
23
|
+
socket.off("error", onError);
|
|
24
|
+
socket.pause();
|
|
25
|
+
resolve(socket);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function connectSidecarSocket(path) {
|
|
30
|
+
await (0, spawn_sidecar_1.ensureSidecarRunning)();
|
|
31
|
+
const port = (0, spawn_sidecar_1.getSidecarPort)();
|
|
32
|
+
const token = (0, spawn_sidecar_1.getSidecarClientToken)();
|
|
33
|
+
if (port === null || !token)
|
|
34
|
+
throw new sidecar_unavailable_error_1.SidecarUnavailableError();
|
|
35
|
+
return openSocket(`ws://${sidecar_1.SIDECAR_LOOPBACK_HOST}:${port}${path}`, token);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=sidecar-socket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar-socket.js","sourceRoot":"","sources":["../../src/lifecycle/sidecar-socket.ts"],"names":[],"mappings":";;;;;AAoCA,oDAMC;AA1CD,4CAA2B;AAC3B,oDAAkE;AAClE,kDAA6D;AAC7D,mDAIyB;AACzB,2EAAsE;AAEtE,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAEnC,SAAS,UAAU,CAAC,GAAW,EAAE,KAAa;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,YAAS,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;YAC7C,UAAU,EAAE,oCAAyB;YACrC,gBAAgB,EAAE,oBAAoB;SACvC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,IAAI,mDAAuB,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YACvB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AASM,KAAK,UAAU,oBAAoB,CAAC,IAAY;IACrD,MAAM,IAAA,oCAAoB,GAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAA,8BAAc,GAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAA,qCAAqB,GAAE,CAAC;IACtC,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,mDAAuB,EAAE,CAAC;IACjE,OAAO,UAAU,CAAC,QAAQ,+BAAqB,IAAI,IAAI,GAAG,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SidecarUnavailableError = void 0;
|
|
4
|
+
class SidecarUnavailableError extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super("dms-ai sidecar is not reachable");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.SidecarUnavailableError = SidecarUnavailableError;
|
|
10
|
+
//# sourceMappingURL=sidecar-unavailable-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar-unavailable-error.js","sourceRoot":"","sources":["../../src/lifecycle/sidecar-unavailable-error.ts"],"names":[],"mappings":";;;AACA,MAAa,uBAAwB,SAAQ,KAAK;IAChD;QACE,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC3C,CAAC;CACF;AAJD,0DAIC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HTTPResult, type RequestContext } from "@antelopejs/interface-api";
|
|
2
|
+
import type { User } from "@antelopejs/interface-dms/auth/db";
|
|
3
|
+
declare const AIChannelsController_base: import("@antelopejs/interface-api").ControllerClass<object>;
|
|
4
|
+
export declare class AIChannelsController extends AIChannelsController_base {
|
|
5
|
+
events(ctx: RequestContext, channels: string, user: User): Promise<HTTPResult | undefined>;
|
|
6
|
+
messages(connectionId: string, _budget: void, body: Buffer, user: User): Promise<HTTPResult>;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AIChannelsController = void 0;
|
|
16
|
+
const interface_api_1 = require("@antelopejs/interface-api");
|
|
17
|
+
const auth_1 = require("@antelopejs/interface-dms/auth");
|
|
18
|
+
const channel_service_1 = require("../channels/channel-service");
|
|
19
|
+
const message_budget_1 = require("../channels/message-budget");
|
|
20
|
+
const channels_1 = require("../constants/channels");
|
|
21
|
+
let AIChannelsController = class AIChannelsController extends (0, interface_api_1.Controller)(channels_1.CHANNELS_ROUTE_PREFIX) {
|
|
22
|
+
events(ctx, channels, user) {
|
|
23
|
+
return (0, channel_service_1.openChannel)(ctx, channels, user._id);
|
|
24
|
+
}
|
|
25
|
+
messages(connectionId, _budget, body, user) {
|
|
26
|
+
return (0, channel_service_1.postChannelMessage)(connectionId, user._id, body);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.AIChannelsController = AIChannelsController;
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, interface_api_1.Get)(channels_1.CHANNEL_EVENTS_ROUTE),
|
|
32
|
+
__param(0, (0, interface_api_1.Context)()),
|
|
33
|
+
__param(1, (0, interface_api_1.Parameter)(channels_1.CHANNELS_PARAM, "param")),
|
|
34
|
+
__param(2, (0, auth_1.AuthRawUser)()),
|
|
35
|
+
__metadata("design:type", Function),
|
|
36
|
+
__metadata("design:paramtypes", [Object, String, Function]),
|
|
37
|
+
__metadata("design:returntype", Promise)
|
|
38
|
+
], AIChannelsController.prototype, "events", null);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, interface_api_1.Post)(channels_1.CHANNEL_MESSAGES_ROUTE),
|
|
41
|
+
__param(0, (0, interface_api_1.Parameter)(channels_1.CONNECTION_ID_PARAM, "param")),
|
|
42
|
+
__param(1, (0, message_budget_1.MessageBudget)()),
|
|
43
|
+
__param(2, (0, interface_api_1.RawBody)(channels_1.CHANNEL_MESSAGE_MAX_BYTES)),
|
|
44
|
+
__param(3, (0, auth_1.AuthRawUser)()),
|
|
45
|
+
__metadata("design:type", Function),
|
|
46
|
+
__metadata("design:paramtypes", [String, void 0, Buffer, Function]),
|
|
47
|
+
__metadata("design:returntype", Promise)
|
|
48
|
+
], AIChannelsController.prototype, "messages", null);
|
|
49
|
+
exports.AIChannelsController = AIChannelsController = __decorate([
|
|
50
|
+
(0, auth_1.AuthOwnerOnly)()
|
|
51
|
+
], AIChannelsController);
|
|
52
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/routes/channels.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6DASmC;AACnC,yDAA4E;AAE5E,iEAA8E;AAC9E,+DAA2D;AAC3D,oDAO+B;AASxB,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,IAAA,0BAAU,EAAC,gCAAqB,CAAC;IAEzE,MAAM,CACO,GAAmB,EACM,QAAgB,EACrC,IAAU;QAEzB,OAAO,IAAA,6BAAW,EAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAGD,QAAQ,CACmC,YAAoB,EAC5C,OAAa,EACM,IAAY,EACjC,IAAU;QAEzB,OAAO,IAAA,oCAAkB,EAAC,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF,CAAA;AAnBY,oDAAoB;AAE/B;IADC,IAAA,mBAAG,EAAC,+BAAoB,CAAC;IAEvB,WAAA,IAAA,uBAAO,GAAE,CAAA;IACT,WAAA,IAAA,yBAAS,EAAC,yBAAc,EAAE,OAAO,CAAC,CAAA;IAClC,WAAA,IAAA,kBAAW,GAAE,CAAA;;;;kDAGf;AAGD;IADC,IAAA,oBAAI,EAAC,iCAAsB,CAAC;IAE1B,WAAA,IAAA,yBAAS,EAAC,8BAAmB,EAAE,OAAO,CAAC,CAAA;IACvC,WAAA,IAAA,8BAAa,GAAE,CAAA;IACf,WAAA,IAAA,uBAAO,EAAC,oCAAyB,CAAC,CAAA;IAClC,WAAA,IAAA,kBAAW,GAAE,CAAA;;qDAD4B,MAAM;;oDAIjD;+BAlBU,oBAAoB;IADhC,IAAA,oBAAa,GAAE;GACH,oBAAoB,CAmBhC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type HTTPResult, type RequestContext } from "@antelopejs/interface-api";
|
|
2
|
+
declare const AIChatboxController_base: import("@antelopejs/interface-api").ControllerClass<object>;
|
|
3
|
+
export declare class AIChatboxController extends AIChatboxController_base {
|
|
4
|
+
document(ctx: RequestContext): Promise<HTTPResult | undefined>;
|
|
5
|
+
asset(ctx: RequestContext, path: string): Promise<HTTPResult | undefined>;
|
|
6
|
+
}
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AIChatboxController = void 0;
|
|
16
|
+
const interface_api_1 = require("@antelopejs/interface-api");
|
|
17
|
+
const auth_1 = require("@antelopejs/interface-dms/auth");
|
|
18
|
+
const passthrough_1 = require("../chatbox/passthrough");
|
|
19
|
+
const chatbox_1 = require("../constants/chatbox");
|
|
20
|
+
let AIChatboxController = class AIChatboxController extends (0, interface_api_1.Controller)(chatbox_1.CHATBOX_ROUTE_PREFIX) {
|
|
21
|
+
document(ctx) {
|
|
22
|
+
return (0, passthrough_1.relayChatboxFile)(ctx, chatbox_1.CHATBOX_INDEX_PATH);
|
|
23
|
+
}
|
|
24
|
+
asset(ctx, path) {
|
|
25
|
+
return (0, passthrough_1.relayChatboxFile)(ctx, `/${path}`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.AIChatboxController = AIChatboxController;
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, interface_api_1.Get)(chatbox_1.CHATBOX_INDEX_ROUTE),
|
|
31
|
+
__param(0, (0, interface_api_1.Context)()),
|
|
32
|
+
__metadata("design:type", Function),
|
|
33
|
+
__metadata("design:paramtypes", [Object]),
|
|
34
|
+
__metadata("design:returntype", Promise)
|
|
35
|
+
], AIChatboxController.prototype, "document", null);
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, interface_api_1.Get)(chatbox_1.CHATBOX_ASSET_ROUTE),
|
|
38
|
+
__param(0, (0, interface_api_1.Context)()),
|
|
39
|
+
__param(1, (0, interface_api_1.Parameter)(chatbox_1.CHATBOX_PATH_PARAM, "param")),
|
|
40
|
+
__metadata("design:type", Function),
|
|
41
|
+
__metadata("design:paramtypes", [Object, String]),
|
|
42
|
+
__metadata("design:returntype", Promise)
|
|
43
|
+
], AIChatboxController.prototype, "asset", null);
|
|
44
|
+
exports.AIChatboxController = AIChatboxController = __decorate([
|
|
45
|
+
(0, auth_1.AuthOwnerOnly)()
|
|
46
|
+
], AIChatboxController);
|
|
47
|
+
//# sourceMappingURL=chatbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatbox.js","sourceRoot":"","sources":["../../src/routes/chatbox.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6DAOmC;AACnC,yDAA+D;AAC/D,wDAA0D;AAC1D,kDAM8B;AAOvB,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,IAAA,0BAAU,EAAC,8BAAoB,CAAC;IAEvE,QAAQ,CAAY,GAAmB;QACrC,OAAO,IAAA,8BAAgB,EAAC,GAAG,EAAE,4BAAkB,CAAC,CAAC;IACnD,CAAC;IAGD,KAAK,CACQ,GAAmB,EACU,IAAY;QAEpD,OAAO,IAAA,8BAAgB,EAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AAbY,kDAAmB;AAE9B;IADC,IAAA,mBAAG,EAAC,6BAAmB,CAAC;IACf,WAAA,IAAA,uBAAO,GAAE,CAAA;;;;mDAElB;AAGD;IADC,IAAA,mBAAG,EAAC,6BAAmB,CAAC;IAEtB,WAAA,IAAA,uBAAO,GAAE,CAAA;IACT,WAAA,IAAA,yBAAS,EAAC,4BAAkB,EAAE,OAAO,CAAC,CAAA;;;;gDAGxC;8BAZU,mBAAmB;IAD/B,IAAA,oBAAa,GAAE;GACH,mBAAmB,CAa/B"}
|
package/dist/routes/index.d.ts
CHANGED
package/dist/routes/index.js
CHANGED
|
@@ -15,6 +15,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./builder"), exports);
|
|
18
|
+
__exportStar(require("./channels"), exports);
|
|
19
|
+
__exportStar(require("./chatbox"), exports);
|
|
18
20
|
__exportStar(require("./health"), exports);
|
|
19
21
|
__exportStar(require("./logs"), exports);
|
|
20
22
|
__exportStar(require("./metrics"), exports);
|
package/dist/routes/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,2CAAyB;AACzB,yCAAuB;AACvB,4CAA0B;AAC1B,mDAAiC;AACjC,6CAA2B;AAC3B,iDAA+B;AAC/B,2CAAyB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,6CAA2B;AAC3B,4CAA0B;AAC1B,2CAAyB;AACzB,yCAAuB;AACvB,4CAA0B;AAC1B,mDAAiC;AACjC,6CAA2B;AAC3B,iDAA+B;AAC/B,2CAAyB"}
|
|
@@ -18,8 +18,6 @@ let AISidecarInfoController = class AISidecarInfoController extends (0, interfac
|
|
|
18
18
|
async sidecarInfo() {
|
|
19
19
|
await (0, spawn_sidecar_1.ensureSidecarRunning)();
|
|
20
20
|
return interface_api_1.HTTPResult.withHeaders({
|
|
21
|
-
port: (0, spawn_sidecar_1.getSidecarPort)(),
|
|
22
|
-
clientToken: (0, spawn_sidecar_1.getSidecarClientToken)(),
|
|
23
21
|
isRunning: (0, spawn_sidecar_1.isSidecarRunning)(),
|
|
24
22
|
hasGivenUp: (0, spawn_sidecar_1.hasSidecarGivenUp)(),
|
|
25
23
|
disabled: (0, spawn_sidecar_1.isSidecarDisabled)(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidecar-info.js","sourceRoot":"","sources":["../../src/routes/sidecar-info.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6DAAwE;AACxE,yDAA+D;AAC/D,gDAAmD;AACnD,
|
|
1
|
+
{"version":3,"file":"sidecar-info.js","sourceRoot":"","sources":["../../src/routes/sidecar-info.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6DAAwE;AACxE,yDAA+D;AAC/D,gDAAmD;AACnD,8DAKoC;AAO7B,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,IAAA,0BAAU,EAAC,qBAAY,CAAC;IAE7D,AAAN,KAAK,CAAC,WAAW;QAGf,MAAM,IAAA,oCAAoB,GAAE,CAAC;QAC7B,OAAO,0BAAU,CAAC,WAAW,CAC3B;YACE,SAAS,EAAE,IAAA,gCAAgB,GAAE;YAC7B,UAAU,EAAE,IAAA,iCAAiB,GAAE;YAC/B,QAAQ,EAAE,IAAA,iCAAiB,GAAE;SAC9B,EACD,EAAE,eAAe,EAAE,UAAU,EAAE,CAChC,CAAC;IACJ,CAAC;CACF,CAAA;AAfY,0DAAuB;AAE5B;IADL,IAAA,mBAAG,EAAC,eAAe,CAAC;;;;0DAapB;kCAdU,uBAAuB;IADnC,IAAA,oBAAa,GAAE;GACH,uBAAuB,CAenC"}
|
|
@@ -47,6 +47,11 @@ const MODE_OPTIONS: Array<{ value: Mode; label: string; hint: string }> = [
|
|
|
47
47
|
{ value: 'auto', label: 'Auto', hint: 'Auto-approve every tool action' },
|
|
48
48
|
]
|
|
49
49
|
|
|
50
|
+
// Safe mode refuses raw edits whatever the mode, and Auto stops short of
|
|
51
|
+
// approving everything there, so the mode hint says so while it is active.
|
|
52
|
+
const SAFE_MODE_MODE_NOTE =
|
|
53
|
+
'Safe mode: raw edits and shell commands stay blocked, and Auto still asks before other actions.'
|
|
54
|
+
|
|
50
55
|
const PROVIDER_OPTIONS: Array<{
|
|
51
56
|
value: ProviderName
|
|
52
57
|
label: string
|
|
@@ -241,6 +246,9 @@ const SELECT_CLASS =
|
|
|
241
246
|
<p class="mt-1.5 text-xs text-dimmed">
|
|
242
247
|
{{ MODE_OPTIONS.find((o) => o.value === settings.mode)?.hint }}
|
|
243
248
|
</p>
|
|
249
|
+
<p v-if="activeMode === 'safe'" class="mt-1 text-xs text-dimmed">
|
|
250
|
+
{{ SAFE_MODE_MODE_NOTE }}
|
|
251
|
+
</p>
|
|
244
252
|
</div>
|
|
245
253
|
<div>
|
|
246
254
|
<label class="mb-1.5 block text-xs font-medium text-toned">
|
|
@@ -4,85 +4,131 @@ import {
|
|
|
4
4
|
useDmsRouter,
|
|
5
5
|
} from '#dms/frontend-module'
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
type ChannelClient,
|
|
8
|
+
createChannelClient,
|
|
9
|
+
} from '../runtime/channel-client'
|
|
10
|
+
import {
|
|
11
|
+
createChatTransport,
|
|
12
|
+
exposeChatTransport,
|
|
13
|
+
} from '../runtime/chat-transport'
|
|
14
|
+
import {
|
|
15
|
+
CHANNEL_IDLE_STOP_MS,
|
|
16
|
+
CHANNEL_STATUS_RECONNECTING,
|
|
17
|
+
CHAT_CHANNEL,
|
|
18
|
+
CHATBOX_PATH,
|
|
19
|
+
HELLO_MESSAGE_TYPE,
|
|
20
|
+
HOST_CHANNEL,
|
|
21
|
+
HOST_ROLE,
|
|
22
|
+
JSON_CONTENT_TYPE,
|
|
8
23
|
SIDECAR_INFO_PATH,
|
|
9
|
-
SIDECAR_PROBE_HOST,
|
|
10
24
|
SIDECAR_STATUS_CONNECTED,
|
|
11
25
|
SIDECAR_STATUS_REVIVING,
|
|
12
26
|
SIDECAR_STATUS_UNAVAILABLE,
|
|
13
|
-
|
|
14
|
-
WS_STATUS_CONNECTING,
|
|
27
|
+
VISIBILITY_CHANGE_EVENT,
|
|
15
28
|
} from '../runtime/constants'
|
|
16
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
buildCurrentPageUpdate,
|
|
31
|
+
installCurrentPageTracker,
|
|
32
|
+
} from '../runtime/current-page'
|
|
17
33
|
import { registerLauncherAction } from '../runtime/header-action'
|
|
18
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
createHostCommandDispatcher,
|
|
36
|
+
type HostCommandDispatcher,
|
|
37
|
+
} from '../runtime/host-commands'
|
|
19
38
|
import { installNavigationCompleteEmitter } from '../runtime/navigation-complete'
|
|
20
|
-
import { injectOverlay } from '../runtime/overlay'
|
|
39
|
+
import { injectOverlay, type OverlayHandle } from '../runtime/overlay'
|
|
21
40
|
import { runWhenLoggedIn } from '../runtime/session-gate'
|
|
22
41
|
import { installToggleShortcut } from '../runtime/shortcuts'
|
|
23
42
|
import {
|
|
24
43
|
createSidecarStatusController,
|
|
25
44
|
type SidecarStatus,
|
|
45
|
+
type SidecarStatusController,
|
|
26
46
|
} from '../runtime/sidecar-status'
|
|
27
|
-
import { createHostWsClient } from '../runtime/ws-client'
|
|
28
47
|
|
|
29
|
-
|
|
48
|
+
type AuthFetch = ReturnType<typeof useAuthFetch>['$authFetch']
|
|
49
|
+
|
|
50
|
+
interface ChannelDeps {
|
|
51
|
+
$authFetch: AuthFetch
|
|
52
|
+
controller: SidecarStatusController
|
|
53
|
+
dispatchHostCommand: HostCommandDispatcher
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function buildIframeUrl(): string {
|
|
30
57
|
// Seed the chatbox with the host's current light/dark mode so its very first
|
|
31
58
|
// paint matches; the theme bridge keeps it in sync from there on.
|
|
32
59
|
const mode = document.documentElement.classList.contains('dark')
|
|
33
60
|
? 'dark'
|
|
34
61
|
: 'light'
|
|
35
|
-
return `${
|
|
62
|
+
return `${CHATBOX_PATH}?theme=${mode}`
|
|
36
63
|
}
|
|
37
64
|
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sidecarHost: SIDECAR_HOST_NAME,
|
|
63
|
-
getPort: () => controller.getPort(),
|
|
64
|
-
getClientToken: () => controller.getClientToken(),
|
|
65
|
-
onMessage: dispatchHostCommand,
|
|
65
|
+
function createAssistantChannel(deps: ChannelDeps): ChannelClient {
|
|
66
|
+
const chat = createChatTransport({
|
|
67
|
+
send: (msg) => channel.send(CHAT_CHANNEL, msg),
|
|
68
|
+
reconnect: () => channel.reconnectNow(),
|
|
69
|
+
getStatus: () => channel.getStatus(),
|
|
70
|
+
})
|
|
71
|
+
const frameRoutes: Record<string, (raw: string) => void> = {
|
|
72
|
+
[HOST_CHANNEL]: deps.dispatchHostCommand,
|
|
73
|
+
[CHAT_CHANNEL]: chat.deliverFrame,
|
|
74
|
+
}
|
|
75
|
+
const channel = createChannelClient({
|
|
76
|
+
channels: [HOST_CHANNEL, CHAT_CHANNEL],
|
|
77
|
+
post: (path, body) =>
|
|
78
|
+
deps.$authFetch(path, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
body: JSON.stringify(body),
|
|
81
|
+
headers: { 'content-type': JSON_CONTENT_TYPE },
|
|
82
|
+
}),
|
|
83
|
+
onReady: () => {
|
|
84
|
+
channel.send(HOST_CHANNEL, { type: HELLO_MESSAGE_TYPE, role: HOST_ROLE })
|
|
85
|
+
channel.send(HOST_CHANNEL, buildCurrentPageUpdate(window.location.href))
|
|
86
|
+
chat.announceReady()
|
|
87
|
+
},
|
|
88
|
+
onFrame: (name, raw) => frameRoutes[name]?.(raw),
|
|
66
89
|
onStatusChange: (status) => {
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
if (status
|
|
71
|
-
controller.reportWsDown()
|
|
72
|
-
}
|
|
90
|
+
chat.announceStatus(status)
|
|
91
|
+
// The sidecar went away, or dms-ai reloaded: re-probe, which revives
|
|
92
|
+
// an idle-exited sidecar, rather than only waiting on the retries.
|
|
93
|
+
if (status === CHANNEL_STATUS_RECONNECTING) deps.controller.reportChannelDown()
|
|
73
94
|
},
|
|
74
95
|
})
|
|
96
|
+
exposeChatTransport(chat.transport)
|
|
97
|
+
return channel
|
|
98
|
+
}
|
|
75
99
|
|
|
100
|
+
function followPanel(overlay: OverlayHandle, channel: ChannelClient): () => void {
|
|
101
|
+
let stopTimer: ReturnType<typeof setTimeout> | null = null
|
|
102
|
+
const clearStopTimer = (): void => {
|
|
103
|
+
if (stopTimer !== null) clearTimeout(stopTimer)
|
|
104
|
+
stopTimer = null
|
|
105
|
+
}
|
|
106
|
+
const follow = (): void => {
|
|
107
|
+
clearStopTimer()
|
|
108
|
+
const isNeeded = overlay.isOpen() && document.visibilityState === 'visible'
|
|
109
|
+
if (isNeeded) channel.start()
|
|
110
|
+
else stopTimer = setTimeout(() => channel.stop(), CHANNEL_IDLE_STOP_MS)
|
|
111
|
+
}
|
|
112
|
+
const stopOpenChange = overlay.onOpenChange(follow)
|
|
113
|
+
document.addEventListener(VISIBILITY_CHANGE_EVENT, follow)
|
|
114
|
+
follow()
|
|
115
|
+
return () => {
|
|
116
|
+
clearStopTimer()
|
|
117
|
+
stopOpenChange()
|
|
118
|
+
document.removeEventListener(VISIBILITY_CHANGE_EVENT, follow)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function statusApplier(
|
|
123
|
+
overlay: OverlayHandle,
|
|
124
|
+
channel: ChannelClient,
|
|
125
|
+
): (status: SidecarStatus) => void {
|
|
76
126
|
let firstApply = true
|
|
77
|
-
|
|
127
|
+
return (status) => {
|
|
78
128
|
if (status === SIDECAR_STATUS_CONNECTED) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
// On the first apply the socket was just created and is connecting to the
|
|
83
|
-
// right port; only later connects (after a drop or port change) need a
|
|
84
|
-
// forced, backoff-skipping reconnect.
|
|
85
|
-
if (!firstApply) hostWs.reconnectNow()
|
|
129
|
+
overlay.repoint(buildIframeUrl())
|
|
130
|
+
// Only a connect after a drop needs to skip the channel's backoff.
|
|
131
|
+
if (!firstApply) channel.reconnectNow()
|
|
86
132
|
} else if (status === SIDECAR_STATUS_REVIVING) {
|
|
87
133
|
overlay.showPlaceholder('reviving')
|
|
88
134
|
} else if (status === SIDECAR_STATUS_UNAVAILABLE) {
|
|
@@ -92,22 +138,55 @@ async function startAssistant({ vueApp }: DmsAppContext): Promise<void> {
|
|
|
92
138
|
}
|
|
93
139
|
firstApply = false
|
|
94
140
|
}
|
|
95
|
-
|
|
141
|
+
}
|
|
96
142
|
|
|
143
|
+
function installHostState(channel: ChannelClient): () => void {
|
|
97
144
|
const sendWhenConnected = (msg: unknown): void => {
|
|
98
|
-
if (!
|
|
99
|
-
|
|
145
|
+
if (!channel.isConnected()) return
|
|
146
|
+
channel.send(HOST_CHANNEL, msg)
|
|
100
147
|
}
|
|
101
148
|
const stopTracking = installCurrentPageTracker({ send: sendWhenConnected })
|
|
102
149
|
const stopNavigation = installNavigationCompleteEmitter({
|
|
103
150
|
send: sendWhenConnected,
|
|
104
151
|
})
|
|
105
|
-
|
|
152
|
+
return () => {
|
|
106
153
|
stopTracking()
|
|
107
154
|
stopNavigation()
|
|
108
155
|
}
|
|
109
|
-
|
|
110
|
-
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function startAssistant({ vueApp }: DmsAppContext): Promise<void> {
|
|
159
|
+
const { $authFetch } = useAuthFetch()
|
|
160
|
+
const controller = createSidecarStatusController(() =>
|
|
161
|
+
$authFetch(SIDECAR_INFO_PATH),
|
|
162
|
+
)
|
|
163
|
+
// A null/disabled first probe means the assistant shouldn't appear at all —
|
|
164
|
+
// preserve the previous "no icon, no overlay" behavior in that case.
|
|
165
|
+
if (!(await controller.init())) return
|
|
166
|
+
const overlay = injectOverlay()
|
|
167
|
+
if (overlay === null) return
|
|
168
|
+
installToggleShortcut({ onToggle: () => overlay.toggleOpen() })
|
|
169
|
+
// Registered unconditionally (even while reviving) so the launcher is present
|
|
170
|
+
// through an outage; opening it surfaces the panel's own status placeholder.
|
|
171
|
+
registerLauncherAction(() => overlay.toggleFromLauncher())
|
|
172
|
+
// Host-side dev hot reload: a page the agent just wrote is re-registered
|
|
173
|
+
// asynchronously, so each navigation waits for the layout to serve it, one at
|
|
174
|
+
// a time so a burst of commands cannot land out of order.
|
|
175
|
+
const dispatchHostCommand = createHostCommandDispatcher({
|
|
176
|
+
router: useDmsRouter(),
|
|
177
|
+
devReload: useDmsDevReload(),
|
|
178
|
+
})
|
|
179
|
+
const channel = createAssistantChannel({ $authFetch, controller, dispatchHostCommand })
|
|
180
|
+
controller.subscribe(statusApplier(overlay, channel))
|
|
181
|
+
const stopFollowing = followPanel(overlay, channel)
|
|
182
|
+
const stopHostState = installHostState(channel)
|
|
183
|
+
const teardown = (): void => {
|
|
184
|
+
stopFollowing()
|
|
185
|
+
stopHostState()
|
|
186
|
+
channel.stop()
|
|
187
|
+
}
|
|
188
|
+
vueApp.onUnmount(teardown)
|
|
189
|
+
import.meta.hot?.dispose(teardown)
|
|
111
190
|
}
|
|
112
191
|
|
|
113
192
|
export default defineDmsPlugin((context) => {
|