@alfe.ai/openclaw-chat 0.9.5 → 0.9.6
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/plugin.d.cts +9 -0
- package/dist/plugin.d.ts +9 -0
- package/dist/plugin2.cjs +56 -23
- package/dist/plugin2.js +56 -23
- package/package.json +2 -2
package/dist/plugin.d.cts
CHANGED
|
@@ -599,6 +599,15 @@ interface AnchorEnv {
|
|
|
599
599
|
requireMainFilename: string | undefined;
|
|
600
600
|
argv1: string | undefined;
|
|
601
601
|
execPath: string;
|
|
602
|
+
/**
|
|
603
|
+
* Well-known global `node_modules` directories to try as `<dir>/openclaw`
|
|
604
|
+
* anchors, independent of PATH / `which` / execPath. Load-bearing when the
|
|
605
|
+
* plugin runs in-process inside a runtime whose PATH is stripped or whose
|
|
606
|
+
* `child_process` is sandboxed (homebrew-keg self-hosted macOS), so every
|
|
607
|
+
* environment-derived anchor above returns nothing. Optional — defaults to
|
|
608
|
+
* none (tests that don't exercise this pass `undefined`).
|
|
609
|
+
*/
|
|
610
|
+
globalModulesDirs?: string[];
|
|
602
611
|
}
|
|
603
612
|
/**
|
|
604
613
|
* Compute the ordered, de-duplicated list of resolver anchors to try, each
|
package/dist/plugin.d.ts
CHANGED
|
@@ -599,6 +599,15 @@ interface AnchorEnv {
|
|
|
599
599
|
requireMainFilename: string | undefined;
|
|
600
600
|
argv1: string | undefined;
|
|
601
601
|
execPath: string;
|
|
602
|
+
/**
|
|
603
|
+
* Well-known global `node_modules` directories to try as `<dir>/openclaw`
|
|
604
|
+
* anchors, independent of PATH / `which` / execPath. Load-bearing when the
|
|
605
|
+
* plugin runs in-process inside a runtime whose PATH is stripped or whose
|
|
606
|
+
* `child_process` is sandboxed (homebrew-keg self-hosted macOS), so every
|
|
607
|
+
* environment-derived anchor above returns nothing. Optional — defaults to
|
|
608
|
+
* none (tests that don't exercise this pass `undefined`).
|
|
609
|
+
*/
|
|
610
|
+
globalModulesDirs?: string[];
|
|
602
611
|
}
|
|
603
612
|
/**
|
|
604
613
|
* Compute the ordered, de-duplicated list of resolver anchors to try, each
|
package/dist/plugin2.cjs
CHANGED
|
@@ -3,6 +3,7 @@ let node_fs_promises = require("node:fs/promises");
|
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_child_process = require("node:child_process");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
|
+
let node_url = require("node:url");
|
|
6
7
|
let node_os = require("node:os");
|
|
7
8
|
let _alfe_ai_chat = require("@alfe.ai/chat");
|
|
8
9
|
let _alfe_ai_agent_api_client = require("@alfe.ai/agent-api-client");
|
|
@@ -2072,24 +2073,33 @@ let resolveRouteEnvelope = null;
|
|
|
2072
2073
|
* degrades `chat.abort` to a logged no-op (Stop still seals the UI) rather than
|
|
2073
2074
|
* a hard failure.
|
|
2074
2075
|
*/
|
|
2075
|
-
function loadOpenClawSdk(req, log, anchor) {
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2076
|
+
async function loadOpenClawSdk(req, log, anchor) {
|
|
2077
|
+
const loadSubpath = async (subpath) => {
|
|
2078
|
+
try {
|
|
2079
|
+
const mod = await import((0, node_url.pathToFileURL)(req.resolve(subpath)).href);
|
|
2080
|
+
return {
|
|
2081
|
+
...typeof mod.default === "object" ? mod.default : void 0,
|
|
2082
|
+
...mod
|
|
2083
|
+
};
|
|
2084
|
+
} catch {}
|
|
2085
|
+
try {
|
|
2086
|
+
return req(subpath);
|
|
2087
|
+
} catch {
|
|
2088
|
+
return;
|
|
2082
2089
|
}
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2090
|
+
};
|
|
2091
|
+
let resolvedDispatch = false;
|
|
2092
|
+
const channelInbound = await loadSubpath("openclaw/plugin-sdk/channel-inbound");
|
|
2093
|
+
if (channelInbound?.dispatchInboundDirectDmWithRuntime) {
|
|
2094
|
+
dispatchInbound = channelInbound.dispatchInboundDirectDmWithRuntime;
|
|
2095
|
+
resolvedDispatch = true;
|
|
2096
|
+
}
|
|
2097
|
+
const harness = await loadSubpath("openclaw/plugin-sdk/agent-harness");
|
|
2098
|
+
const abortRun = harness?.abortAgentHarnessRun ?? harness?.abortEmbeddedAgentRun;
|
|
2099
|
+
if (abortRun) abortEmbeddedAgentRun = abortRun;
|
|
2100
|
+
if (harness?.resolveActiveEmbeddedRunSessionId) resolveActiveRunSessionId = harness.resolveActiveEmbeddedRunSessionId;
|
|
2101
|
+
const envelope = await loadSubpath("openclaw/plugin-sdk/inbound-envelope");
|
|
2102
|
+
if (envelope?.resolveInboundRouteEnvelopeBuilderWithRuntime) resolveRouteEnvelope = envelope.resolveInboundRouteEnvelopeBuilderWithRuntime;
|
|
2093
2103
|
if (resolvedDispatch) log.info(`Resolved OpenClaw SDK from ${anchor} (hard-abort=${abortEmbeddedAgentRun && resolveActiveRunSessionId ? "available" : "unavailable"})`);
|
|
2094
2104
|
return resolvedDispatch;
|
|
2095
2105
|
}
|
|
@@ -2160,6 +2170,7 @@ function computeOpenClawSdkAnchors(deps) {
|
|
|
2160
2170
|
try {
|
|
2161
2171
|
push(deps.which("openclaw"));
|
|
2162
2172
|
} catch {}
|
|
2173
|
+
for (const dir of deps.globalModulesDirs ?? []) push((0, node_path.join)(dir, "openclaw", "package.json"));
|
|
2163
2174
|
for (const base of [deps.execPath, safeRealpath(deps.realpath, deps.execPath)]) {
|
|
2164
2175
|
if (!base) continue;
|
|
2165
2176
|
try {
|
|
@@ -2178,6 +2189,27 @@ function safeRealpath(realpath, p) {
|
|
|
2178
2189
|
}
|
|
2179
2190
|
}
|
|
2180
2191
|
/**
|
|
2192
|
+
* Well-known global `node_modules` locations to try as SDK anchors, in priority
|
|
2193
|
+
* order. Environment-INDEPENDENT (no PATH / `which` / execPath), so they resolve
|
|
2194
|
+
* the SDK even when the in-process plugin context has a stripped PATH or a
|
|
2195
|
+
* sandboxed `child_process` (the homebrew-keg self-hosted macOS case where every
|
|
2196
|
+
* environment-derived anchor returns nothing). Non-existent candidates are
|
|
2197
|
+
* harmless — `createRequire` just fails and the next anchor runs. `NODE_PATH`,
|
|
2198
|
+
* when set, is an explicit module-dir list, so honour it too.
|
|
2199
|
+
*/
|
|
2200
|
+
function candidateGlobalModulesDirs() {
|
|
2201
|
+
const dirs = [
|
|
2202
|
+
"/opt/homebrew/lib/node_modules",
|
|
2203
|
+
"/usr/local/lib/node_modules",
|
|
2204
|
+
"/usr/lib/node_modules",
|
|
2205
|
+
"/usr/local/share/npm/lib/node_modules"
|
|
2206
|
+
];
|
|
2207
|
+
const home = process.env.HOME;
|
|
2208
|
+
if (home) dirs.push((0, node_path.join)(home, ".npm-global", "lib", "node_modules"));
|
|
2209
|
+
for (const d of (process.env.NODE_PATH ?? "").split(node_path.delimiter)) if (d) dirs.push(d);
|
|
2210
|
+
return dirs;
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2181
2213
|
* Resolve OpenClaw SDK functions from the running process.
|
|
2182
2214
|
*
|
|
2183
2215
|
* The openclaw package is NOT in the plugin's node_modules (it's a peer dep).
|
|
@@ -2186,19 +2218,20 @@ function safeRealpath(realpath, p) {
|
|
|
2186
2218
|
* relocated-node layouts), then to a `which openclaw` lookup, then fall back to
|
|
2187
2219
|
* deriving the global modules path from process.execPath.
|
|
2188
2220
|
*/
|
|
2189
|
-
function resolveOpenClawSdk(log) {
|
|
2221
|
+
async function resolveOpenClawSdk(log) {
|
|
2190
2222
|
const pathEnv = process.env.PATH;
|
|
2191
2223
|
const anchors = computeOpenClawSdkAnchors({
|
|
2192
2224
|
realpath: node_fs.realpathSync,
|
|
2193
2225
|
which: () => whichOpenClaw(pathEnv),
|
|
2194
2226
|
requireMainFilename: require$1.main?.filename,
|
|
2195
2227
|
argv1: process.argv[1],
|
|
2196
|
-
execPath: process.execPath
|
|
2228
|
+
execPath: process.execPath,
|
|
2229
|
+
globalModulesDirs: candidateGlobalModulesDirs()
|
|
2197
2230
|
});
|
|
2198
2231
|
for (const anchor of anchors) try {
|
|
2199
|
-
if (loadOpenClawSdk((0, node_module.createRequire)(anchor), log, anchor)) return;
|
|
2232
|
+
if (await loadOpenClawSdk((0, node_module.createRequire)(anchor), log, anchor)) return;
|
|
2200
2233
|
} catch {}
|
|
2201
|
-
log.warn(
|
|
2234
|
+
log.warn(`OpenClaw SDK not resolvable — chat dispatch will not work. argv1=${process.argv[1] ?? "<none>"} execPath=${process.execPath} PATH=${pathEnv ? "set" : "EMPTY"} anchorsTried=[${anchors.join(", ")}]`);
|
|
2202
2235
|
}
|
|
2203
2236
|
let pluginRuntime = null;
|
|
2204
2237
|
let chatClient = null;
|
|
@@ -2945,7 +2978,7 @@ const plugin = {
|
|
|
2945
2978
|
log.info(`Registered ${String(a2aTools.length)} agent tools`);
|
|
2946
2979
|
}
|
|
2947
2980
|
const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
|
|
2948
|
-
const startChatService = () => {
|
|
2981
|
+
const startChatService = async () => {
|
|
2949
2982
|
const action = decideChatServiceStart({
|
|
2950
2983
|
connectInFlight: connectingPromise !== null,
|
|
2951
2984
|
clientPresent: chatClient !== null,
|
|
@@ -2966,7 +2999,7 @@ const plugin = {
|
|
|
2966
2999
|
}
|
|
2967
3000
|
globalThis.__alfeChatPluginActivated = true;
|
|
2968
3001
|
log.info("Chat plugin registering...");
|
|
2969
|
-
resolveOpenClawSdk(log);
|
|
3002
|
+
await resolveOpenClawSdk(log);
|
|
2970
3003
|
pluginRuntime = api.runtime ?? null;
|
|
2971
3004
|
let thisConnect = null;
|
|
2972
3005
|
thisConnect = Promise.resolve().then(() => {
|
package/dist/plugin2.js
CHANGED
|
@@ -3,6 +3,7 @@ import { mkdir, open, readFile, readdir, stat, unlink, writeFile } from "node:fs
|
|
|
3
3
|
import { existsSync, realpathSync } from "node:fs";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
5
|
import { basename, delimiter, dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
6
7
|
import { homedir } from "node:os";
|
|
7
8
|
import { ChatServiceClient, resolveAlfeChat } from "@alfe.ai/chat";
|
|
8
9
|
import { AgentApiClient, installToolErrorCapture } from "@alfe.ai/agent-api-client";
|
|
@@ -2072,24 +2073,33 @@ let resolveRouteEnvelope = null;
|
|
|
2072
2073
|
* degrades `chat.abort` to a logged no-op (Stop still seals the UI) rather than
|
|
2073
2074
|
* a hard failure.
|
|
2074
2075
|
*/
|
|
2075
|
-
function loadOpenClawSdk(req, log, anchor) {
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2076
|
+
async function loadOpenClawSdk(req, log, anchor) {
|
|
2077
|
+
const loadSubpath = async (subpath) => {
|
|
2078
|
+
try {
|
|
2079
|
+
const mod = await import(pathToFileURL(req.resolve(subpath)).href);
|
|
2080
|
+
return {
|
|
2081
|
+
...typeof mod.default === "object" ? mod.default : void 0,
|
|
2082
|
+
...mod
|
|
2083
|
+
};
|
|
2084
|
+
} catch {}
|
|
2085
|
+
try {
|
|
2086
|
+
return req(subpath);
|
|
2087
|
+
} catch {
|
|
2088
|
+
return;
|
|
2082
2089
|
}
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2090
|
+
};
|
|
2091
|
+
let resolvedDispatch = false;
|
|
2092
|
+
const channelInbound = await loadSubpath("openclaw/plugin-sdk/channel-inbound");
|
|
2093
|
+
if (channelInbound?.dispatchInboundDirectDmWithRuntime) {
|
|
2094
|
+
dispatchInbound = channelInbound.dispatchInboundDirectDmWithRuntime;
|
|
2095
|
+
resolvedDispatch = true;
|
|
2096
|
+
}
|
|
2097
|
+
const harness = await loadSubpath("openclaw/plugin-sdk/agent-harness");
|
|
2098
|
+
const abortRun = harness?.abortAgentHarnessRun ?? harness?.abortEmbeddedAgentRun;
|
|
2099
|
+
if (abortRun) abortEmbeddedAgentRun = abortRun;
|
|
2100
|
+
if (harness?.resolveActiveEmbeddedRunSessionId) resolveActiveRunSessionId = harness.resolveActiveEmbeddedRunSessionId;
|
|
2101
|
+
const envelope = await loadSubpath("openclaw/plugin-sdk/inbound-envelope");
|
|
2102
|
+
if (envelope?.resolveInboundRouteEnvelopeBuilderWithRuntime) resolveRouteEnvelope = envelope.resolveInboundRouteEnvelopeBuilderWithRuntime;
|
|
2093
2103
|
if (resolvedDispatch) log.info(`Resolved OpenClaw SDK from ${anchor} (hard-abort=${abortEmbeddedAgentRun && resolveActiveRunSessionId ? "available" : "unavailable"})`);
|
|
2094
2104
|
return resolvedDispatch;
|
|
2095
2105
|
}
|
|
@@ -2160,6 +2170,7 @@ function computeOpenClawSdkAnchors(deps) {
|
|
|
2160
2170
|
try {
|
|
2161
2171
|
push(deps.which("openclaw"));
|
|
2162
2172
|
} catch {}
|
|
2173
|
+
for (const dir of deps.globalModulesDirs ?? []) push(join(dir, "openclaw", "package.json"));
|
|
2163
2174
|
for (const base of [deps.execPath, safeRealpath(deps.realpath, deps.execPath)]) {
|
|
2164
2175
|
if (!base) continue;
|
|
2165
2176
|
try {
|
|
@@ -2178,6 +2189,27 @@ function safeRealpath(realpath, p) {
|
|
|
2178
2189
|
}
|
|
2179
2190
|
}
|
|
2180
2191
|
/**
|
|
2192
|
+
* Well-known global `node_modules` locations to try as SDK anchors, in priority
|
|
2193
|
+
* order. Environment-INDEPENDENT (no PATH / `which` / execPath), so they resolve
|
|
2194
|
+
* the SDK even when the in-process plugin context has a stripped PATH or a
|
|
2195
|
+
* sandboxed `child_process` (the homebrew-keg self-hosted macOS case where every
|
|
2196
|
+
* environment-derived anchor returns nothing). Non-existent candidates are
|
|
2197
|
+
* harmless — `createRequire` just fails and the next anchor runs. `NODE_PATH`,
|
|
2198
|
+
* when set, is an explicit module-dir list, so honour it too.
|
|
2199
|
+
*/
|
|
2200
|
+
function candidateGlobalModulesDirs() {
|
|
2201
|
+
const dirs = [
|
|
2202
|
+
"/opt/homebrew/lib/node_modules",
|
|
2203
|
+
"/usr/local/lib/node_modules",
|
|
2204
|
+
"/usr/lib/node_modules",
|
|
2205
|
+
"/usr/local/share/npm/lib/node_modules"
|
|
2206
|
+
];
|
|
2207
|
+
const home = process.env.HOME;
|
|
2208
|
+
if (home) dirs.push(join(home, ".npm-global", "lib", "node_modules"));
|
|
2209
|
+
for (const d of (process.env.NODE_PATH ?? "").split(delimiter)) if (d) dirs.push(d);
|
|
2210
|
+
return dirs;
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2181
2213
|
* Resolve OpenClaw SDK functions from the running process.
|
|
2182
2214
|
*
|
|
2183
2215
|
* The openclaw package is NOT in the plugin's node_modules (it's a peer dep).
|
|
@@ -2186,19 +2218,20 @@ function safeRealpath(realpath, p) {
|
|
|
2186
2218
|
* relocated-node layouts), then to a `which openclaw` lookup, then fall back to
|
|
2187
2219
|
* deriving the global modules path from process.execPath.
|
|
2188
2220
|
*/
|
|
2189
|
-
function resolveOpenClawSdk(log) {
|
|
2221
|
+
async function resolveOpenClawSdk(log) {
|
|
2190
2222
|
const pathEnv = process.env.PATH;
|
|
2191
2223
|
const anchors = computeOpenClawSdkAnchors({
|
|
2192
2224
|
realpath: realpathSync,
|
|
2193
2225
|
which: () => whichOpenClaw(pathEnv),
|
|
2194
2226
|
requireMainFilename: require.main?.filename,
|
|
2195
2227
|
argv1: process.argv[1],
|
|
2196
|
-
execPath: process.execPath
|
|
2228
|
+
execPath: process.execPath,
|
|
2229
|
+
globalModulesDirs: candidateGlobalModulesDirs()
|
|
2197
2230
|
});
|
|
2198
2231
|
for (const anchor of anchors) try {
|
|
2199
|
-
if (loadOpenClawSdk(createRequire(anchor), log, anchor)) return;
|
|
2232
|
+
if (await loadOpenClawSdk(createRequire(anchor), log, anchor)) return;
|
|
2200
2233
|
} catch {}
|
|
2201
|
-
log.warn(
|
|
2234
|
+
log.warn(`OpenClaw SDK not resolvable — chat dispatch will not work. argv1=${process.argv[1] ?? "<none>"} execPath=${process.execPath} PATH=${pathEnv ? "set" : "EMPTY"} anchorsTried=[${anchors.join(", ")}]`);
|
|
2202
2235
|
}
|
|
2203
2236
|
let pluginRuntime = null;
|
|
2204
2237
|
let chatClient = null;
|
|
@@ -2945,7 +2978,7 @@ const plugin = {
|
|
|
2945
2978
|
log.info(`Registered ${String(a2aTools.length)} agent tools`);
|
|
2946
2979
|
}
|
|
2947
2980
|
const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
|
|
2948
|
-
const startChatService = () => {
|
|
2981
|
+
const startChatService = async () => {
|
|
2949
2982
|
const action = decideChatServiceStart({
|
|
2950
2983
|
connectInFlight: connectingPromise !== null,
|
|
2951
2984
|
clientPresent: chatClient !== null,
|
|
@@ -2966,7 +2999,7 @@ const plugin = {
|
|
|
2966
2999
|
}
|
|
2967
3000
|
globalThis.__alfeChatPluginActivated = true;
|
|
2968
3001
|
log.info("Chat plugin registering...");
|
|
2969
|
-
resolveOpenClawSdk(log);
|
|
3002
|
+
await resolveOpenClawSdk(log);
|
|
2970
3003
|
pluginRuntime = api.runtime ?? null;
|
|
2971
3004
|
let thisConnect = null;
|
|
2972
3005
|
thisConnect = Promise.resolve().then(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/openclaw-chat",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "OpenClaw chat plugin for Alfe — web widget and mobile app channels",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/plugin.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"openclaw.plugin.json"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@alfe.ai/agent-api-client": "^0.
|
|
30
|
+
"@alfe.ai/agent-api-client": "^0.11.0",
|
|
31
31
|
"@alfe.ai/chat": "^0.0.16",
|
|
32
32
|
"@alfe.ai/config": "^0.3.0"
|
|
33
33
|
},
|