@openclaw-cloud/agent-controller 0.19.0-beta.2 → 0.19.0-beta.21
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/commands/install-deps.js +1 -7
- package/dist/commands/install-deps.js.map +1 -1
- package/dist/commands/self-update.js +29 -18
- package/dist/commands/self-update.js.map +1 -1
- package/dist/config-file.js +1 -1
- package/dist/config-file.js.map +1 -1
- package/dist/connection.d.ts +3 -0
- package/dist/connection.js +21 -7
- package/dist/connection.js.map +1 -1
- package/dist/handlers/backup.js +2 -0
- package/dist/handlers/backup.js.map +1 -1
- package/dist/handlers/file-delete.js +2 -0
- package/dist/handlers/file-delete.js.map +1 -1
- package/dist/handlers/file-write.js +2 -0
- package/dist/handlers/file-write.js.map +1 -1
- package/dist/handlers/package-install.js +2 -0
- package/dist/handlers/package-install.js.map +1 -1
- package/dist/handlers/restart.js +3 -1
- package/dist/handlers/restart.js.map +1 -1
- package/dist/handlers/self-update.js +2 -0
- package/dist/handlers/self-update.js.map +1 -1
- package/dist/handlers/update-config.d.ts +3 -0
- package/dist/handlers/update-config.js +22 -0
- package/dist/handlers/update-config.js.map +1 -0
- package/dist/handlers/update-skills.js +2 -0
- package/dist/handlers/update-skills.js.map +1 -1
- package/dist/heartbeat.js +62 -2
- package/dist/heartbeat.js.map +1 -1
- package/dist/index.js +17 -16
- package/dist/index.js.map +1 -1
- package/dist/lockfile.js +12 -3
- package/dist/lockfile.js.map +1 -1
- package/dist/providers/chat-types.d.ts +19 -2
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/openclaw/device-identity.d.ts +20 -0
- package/dist/providers/openclaw/device-identity.js +76 -0
- package/dist/providers/openclaw/device-identity.js.map +1 -0
- package/dist/providers/openclaw/gateway-adapter.d.ts +7 -1
- package/dist/providers/openclaw/gateway-adapter.js +140 -8
- package/dist/providers/openclaw/gateway-adapter.js.map +1 -1
- package/dist/providers/openclaw/gateway-client.d.ts +5 -0
- package/dist/providers/openclaw/gateway-client.js +59 -2
- package/dist/providers/openclaw/gateway-client.js.map +1 -1
- package/dist/providers/types.d.ts +2 -2
- package/dist/types.d.ts +1 -1
- package/dist/utils/apply-config.d.ts +9 -0
- package/dist/utils/apply-config.js +120 -0
- package/dist/utils/apply-config.js.map +1 -0
- package/dist/utils/claude-env.js +34 -46
- package/dist/utils/claude-env.js.map +1 -1
- package/dist/utils/log-collector.d.ts +23 -0
- package/dist/utils/log-collector.js +56 -0
- package/dist/utils/log-collector.js.map +1 -0
- package/dist/utils/release-channel.d.ts +1 -1
- package/dist/utils/release-channel.js +1 -1
- package/dist/utils/release-channel.js.map +1 -1
- package/package.json +1 -1
- package/dist/handlers/config.d.ts +0 -2
- package/dist/handlers/config.js +0 -50
- package/dist/handlers/config.js.map +0 -1
- package/dist/handlers/update-auth-profiles.d.ts +0 -2
- package/dist/handlers/update-auth-profiles.js +0 -67
- package/dist/handlers/update-auth-profiles.js.map +0 -1
- package/dist/handlers/update-env.d.ts +0 -2
- package/dist/handlers/update-env.js +0 -54
- package/dist/handlers/update-env.js.map +0 -1
- package/dist/openclaw/gateway-adapter.d.ts +0 -5
- package/dist/openclaw/gateway-adapter.js +0 -6
- package/dist/openclaw/gateway-adapter.js.map +0 -1
- package/dist/openclaw/gateway-client.d.ts +0 -21
- package/dist/openclaw/gateway-client.js +0 -138
- package/dist/openclaw/gateway-client.js.map +0 -1
- package/dist/openclaw/index.d.ts +0 -20
- package/dist/openclaw/index.js +0 -45
- package/dist/openclaw/index.js.map +0 -1
- package/dist/openclaw/types.d.ts +0 -5
- package/dist/openclaw/types.js +0 -2
- package/dist/openclaw/types.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
-
import {
|
|
5
|
-
import { homedir } from 'node:os';
|
|
6
|
-
import { createConnection, subscribeToChannel } from './connection.js';
|
|
4
|
+
import { createConnection, subscribeToChannel, logCollector } from './connection.js';
|
|
7
5
|
import { startHeartbeat } from './heartbeat.js';
|
|
8
6
|
import { createAgentApi } from './api.js';
|
|
9
7
|
import { BoardHandler } from './handlers/board-handler.js';
|
|
@@ -11,29 +9,31 @@ import { configureProvider, createProvider, getProvider } from './providers/inde
|
|
|
11
9
|
import { DEBUG } from './debug.js';
|
|
12
10
|
import { requireEnv, getBackendUrl } from './utils/env.js';
|
|
13
11
|
import { createLockFile } from './lockfile.js';
|
|
12
|
+
import { applyBootstrapConfig } from './utils/apply-config.js';
|
|
14
13
|
const _require = createRequire(import.meta.url);
|
|
15
14
|
const { version: CONTROLLER_VERSION } = _require(join(dirname(fileURLToPath(import.meta.url)), '../package.json'));
|
|
16
|
-
/**
|
|
17
|
-
function
|
|
18
|
-
const
|
|
19
|
-
|
|
15
|
+
/** On startup, fetch latest config from bootstrap API and apply */
|
|
16
|
+
async function refreshConfigFromBootstrap() {
|
|
17
|
+
const backendUrl = getBackendUrl();
|
|
18
|
+
const agentToken = process.env.AGENT_TOKEN;
|
|
19
|
+
const agentId = process.env.AGENT_ID;
|
|
20
|
+
if (!backendUrl || !agentToken || !agentId)
|
|
20
21
|
return;
|
|
21
|
-
const agentDir = join(process.env.OPENCLAW_STATE_DIR?.trim() || join(homedir(), '.openclaw'), 'agents', 'main', 'agent');
|
|
22
|
-
const filePath = join(agentDir, 'auth-profiles.json');
|
|
23
|
-
if (existsSync(filePath))
|
|
24
|
-
return; // already written (restart)
|
|
25
22
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
const api = createAgentApi(backendUrl, agentToken);
|
|
24
|
+
const data = await api.agentBootstrap(agentId);
|
|
25
|
+
await applyBootstrapConfig(data);
|
|
26
|
+
console.log('[startup] Config refreshed from bootstrap API');
|
|
29
27
|
}
|
|
30
28
|
catch (err) {
|
|
31
|
-
console.error('[
|
|
29
|
+
console.error('[startup] Failed to refresh config from bootstrap:', err instanceof Error ? err.message : err);
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
export function main() {
|
|
35
33
|
createLockFile();
|
|
36
|
-
|
|
34
|
+
refreshConfigFromBootstrap().catch((err) => {
|
|
35
|
+
console.error('[startup] refreshConfigFromBootstrap failed:', err);
|
|
36
|
+
});
|
|
37
37
|
const url = requireEnv('CENTRIFUGO_URL');
|
|
38
38
|
const token = requireEnv('AGENT_TOKEN');
|
|
39
39
|
const agentId = requireEnv('AGENT_ID');
|
|
@@ -108,6 +108,7 @@ export function main() {
|
|
|
108
108
|
heartbeatHandle.stop();
|
|
109
109
|
boardSub?.unsubscribe();
|
|
110
110
|
getProvider()?.disconnect();
|
|
111
|
+
logCollector?.shutdown().catch(() => { });
|
|
111
112
|
client.disconnect();
|
|
112
113
|
// SHUT-4: In-flight commands that are still executing when SIGTERM arrives will not
|
|
113
114
|
// have their responses delivered. This is acceptable — the backend times out and
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lockfile.js
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
|
|
3
|
+
import os from 'node:os';
|
|
4
4
|
const LOCK_FILE = 'agent-controller.lock';
|
|
5
|
+
function getLockDir() {
|
|
6
|
+
// VM/K8s: /opt/openclaw-cloud/agent-controller
|
|
7
|
+
// Standalone: ~/.openclaw/agent-controller
|
|
8
|
+
if (fs.existsSync('/opt/openclaw-cloud/agent-controller')) {
|
|
9
|
+
return '/opt/openclaw-cloud/agent-controller';
|
|
10
|
+
}
|
|
11
|
+
return path.join(os.homedir(), '.openclaw', 'agent-controller');
|
|
12
|
+
}
|
|
5
13
|
function getLockPath() {
|
|
6
|
-
return path.join(
|
|
14
|
+
return path.join(getLockDir(), LOCK_FILE);
|
|
7
15
|
}
|
|
8
16
|
/** Create lock file on startup */
|
|
9
17
|
export function createLockFile() {
|
|
10
18
|
try {
|
|
11
|
-
|
|
19
|
+
const lockDir = getLockDir();
|
|
20
|
+
fs.mkdirSync(lockDir, { recursive: true });
|
|
12
21
|
fs.writeFileSync(getLockPath(), String(process.pid), { mode: 0o644 });
|
|
13
22
|
console.log(`[lock] Created lock file: ${getLockPath()}`);
|
|
14
23
|
}
|
package/dist/lockfile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,SAAS,UAAU;IACjB,+CAA+C;IAC/C,2CAA2C;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,sCAAsC,CAAC,EAAE,CAAC;QAC1D,OAAO,sCAAsC,CAAC;IAChD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,6BAA6B,WAAW,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,6BAA6B,WAAW,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -10,9 +10,26 @@ export interface ChatSession {
|
|
|
10
10
|
updatedAt: number;
|
|
11
11
|
model?: string;
|
|
12
12
|
}
|
|
13
|
+
export interface ChatContentBlock {
|
|
14
|
+
type: string;
|
|
15
|
+
text?: string;
|
|
16
|
+
omitted?: boolean;
|
|
17
|
+
bytes?: number;
|
|
18
|
+
media_type?: string;
|
|
19
|
+
source?: {
|
|
20
|
+
type: string;
|
|
21
|
+
media_type: string;
|
|
22
|
+
data: string;
|
|
23
|
+
};
|
|
24
|
+
name?: string;
|
|
25
|
+
id?: string;
|
|
26
|
+
input?: unknown;
|
|
27
|
+
content?: string | ChatContentBlock[];
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
13
30
|
export interface ChatMessage {
|
|
14
|
-
role: 'user' | 'assistant';
|
|
15
|
-
content: string;
|
|
31
|
+
role: 'user' | 'assistant' | 'toolResult';
|
|
32
|
+
content: string | ChatContentBlock[];
|
|
16
33
|
timestamp: string;
|
|
17
34
|
}
|
|
18
35
|
export interface ChatAttachment {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IAgentProvider } from './types.js';
|
|
2
2
|
export type { IAgentProvider, AgentHealthStatus, SendMessageParams } from './types.js';
|
|
3
|
-
export type { ChatSession, ChatMessage, ChatAttachment, IChatProvider } from './chat-types.js';
|
|
3
|
+
export type { ChatSession, ChatMessage, ChatAttachment, ChatContentBlock, IChatProvider } from './chat-types.js';
|
|
4
4
|
export { OpenclawProvider } from './openclaw/index.js';
|
|
5
5
|
export { MockProvider } from './mock/index.js';
|
|
6
6
|
export type { MockAction } from './mock/index.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface DeviceIdentity {
|
|
2
|
+
deviceId: string;
|
|
3
|
+
publicKeyPem: string;
|
|
4
|
+
privateKeyPem: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function publicKeyRawBase64Url(publicKeyPem: string): string;
|
|
7
|
+
export declare function signPayload(privateKeyPem: string, payload: string): string;
|
|
8
|
+
export declare function buildDeviceAuthPayloadV3(params: {
|
|
9
|
+
deviceId: string;
|
|
10
|
+
clientId: string;
|
|
11
|
+
clientMode: string;
|
|
12
|
+
role: string;
|
|
13
|
+
scopes: string[];
|
|
14
|
+
signedAtMs: number;
|
|
15
|
+
token: string;
|
|
16
|
+
nonce: string;
|
|
17
|
+
platform: string;
|
|
18
|
+
deviceFamily: string;
|
|
19
|
+
}): string;
|
|
20
|
+
export declare function loadOrCreateDeviceIdentity(): DeviceIdentity;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');
|
|
6
|
+
function base64UrlEncode(buf) {
|
|
7
|
+
return buf.toString('base64').replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/g, '');
|
|
8
|
+
}
|
|
9
|
+
function derivePublicKeyRaw(publicKeyPem) {
|
|
10
|
+
const key = crypto.createPublicKey(publicKeyPem);
|
|
11
|
+
const spki = key.export({ type: 'spki', format: 'der' });
|
|
12
|
+
if (spki.length === ED25519_SPKI_PREFIX.length + 32 &&
|
|
13
|
+
spki.subarray(0, ED25519_SPKI_PREFIX.length).equals(ED25519_SPKI_PREFIX)) {
|
|
14
|
+
return spki.subarray(ED25519_SPKI_PREFIX.length);
|
|
15
|
+
}
|
|
16
|
+
return spki;
|
|
17
|
+
}
|
|
18
|
+
function fingerprintPublicKey(publicKeyPem) {
|
|
19
|
+
const raw = derivePublicKeyRaw(publicKeyPem);
|
|
20
|
+
return crypto.createHash('sha256').update(raw).digest('hex');
|
|
21
|
+
}
|
|
22
|
+
export function publicKeyRawBase64Url(publicKeyPem) {
|
|
23
|
+
return base64UrlEncode(derivePublicKeyRaw(publicKeyPem));
|
|
24
|
+
}
|
|
25
|
+
export function signPayload(privateKeyPem, payload) {
|
|
26
|
+
const key = crypto.createPrivateKey(privateKeyPem);
|
|
27
|
+
const sig = crypto.sign(null, Buffer.from(payload, 'utf8'), key);
|
|
28
|
+
return base64UrlEncode(sig);
|
|
29
|
+
}
|
|
30
|
+
export function buildDeviceAuthPayloadV3(params) {
|
|
31
|
+
return [
|
|
32
|
+
'v3',
|
|
33
|
+
params.deviceId,
|
|
34
|
+
params.clientId,
|
|
35
|
+
params.clientMode,
|
|
36
|
+
params.role,
|
|
37
|
+
params.scopes.join(','),
|
|
38
|
+
String(params.signedAtMs),
|
|
39
|
+
params.token,
|
|
40
|
+
params.nonce,
|
|
41
|
+
params.platform,
|
|
42
|
+
params.deviceFamily,
|
|
43
|
+
].join('|');
|
|
44
|
+
}
|
|
45
|
+
function getIdentityPath() {
|
|
46
|
+
const stateDir = process.env.OPENCLAW_STATE_DIR?.trim() || path.join(os.homedir(), '.openclaw');
|
|
47
|
+
return path.join(stateDir, 'identity', 'device.json');
|
|
48
|
+
}
|
|
49
|
+
export function loadOrCreateDeviceIdentity() {
|
|
50
|
+
const filePath = getIdentityPath();
|
|
51
|
+
try {
|
|
52
|
+
if (fs.existsSync(filePath)) {
|
|
53
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
54
|
+
const parsed = JSON.parse(raw);
|
|
55
|
+
if (parsed?.version === 1 && parsed.deviceId && parsed.publicKeyPem && parsed.privateKeyPem) {
|
|
56
|
+
return {
|
|
57
|
+
deviceId: fingerprintPublicKey(parsed.publicKeyPem),
|
|
58
|
+
publicKeyPem: parsed.publicKeyPem,
|
|
59
|
+
privateKeyPem: parsed.privateKeyPem,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// regenerate
|
|
66
|
+
}
|
|
67
|
+
const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
|
|
68
|
+
const publicKeyPem = publicKey.export({ type: 'spki', format: 'pem' }).toString();
|
|
69
|
+
const privateKeyPem = privateKey.export({ type: 'pkcs8', format: 'pem' }).toString();
|
|
70
|
+
const deviceId = fingerprintPublicKey(publicKeyPem);
|
|
71
|
+
const identity = { deviceId, publicKeyPem, privateKeyPem };
|
|
72
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
73
|
+
fs.writeFileSync(filePath, JSON.stringify({ version: 1, ...identity, createdAtMs: Date.now() }, null, 2) + '\n', { mode: 0o600 });
|
|
74
|
+
return identity;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=device-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-identity.js","sourceRoot":"","sources":["../../../src/providers/openclaw/device-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { IChatProvider } from '../chat-types.js';
|
|
2
|
-
import type { ChatSession, ChatMessage, ChatAttachment } from '../chat-types.js';
|
|
2
|
+
import type { ChatSession, ChatMessage, ChatAttachment, ChatContentBlock } from '../chat-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Process content blocks: resolve MEDIA: text references to inline base64 blocks.
|
|
5
|
+
* - Text block with "MEDIA:/path/to/file.png" → replaced with image/file block
|
|
6
|
+
* - Text block with "MEDIA:/path" mixed with other text → MEDIA part extracted, rest stays as text
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveMediaBlocks(blocks: ChatContentBlock[]): ChatContentBlock[];
|
|
3
9
|
export declare class OpenclawGatewayAdapter implements IChatProvider {
|
|
4
10
|
private client;
|
|
5
11
|
private streamCallbacks;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { GatewayClient } from './gateway-client.js';
|
|
2
4
|
import { toErrorMessage } from '../../utils/response.js';
|
|
3
5
|
const STREAM_TTL = 300_000; // 5 min
|
|
@@ -13,7 +15,7 @@ function extractText(msg) {
|
|
|
13
15
|
return msg;
|
|
14
16
|
if (Array.isArray(msg)) {
|
|
15
17
|
return msg
|
|
16
|
-
.filter((c) => c.type === 'text')
|
|
18
|
+
.filter((c) => c.type === 'text' && c.text)
|
|
17
19
|
.map((c) => c.text)
|
|
18
20
|
.join('');
|
|
19
21
|
}
|
|
@@ -22,7 +24,7 @@ function extractText(msg) {
|
|
|
22
24
|
// {role, content: [...], timestamp} format
|
|
23
25
|
if (Array.isArray(obj['content'])) {
|
|
24
26
|
return obj['content']
|
|
25
|
-
.filter((c) => c.type === 'text')
|
|
27
|
+
.filter((c) => c.type === 'text' && c.text)
|
|
26
28
|
.map((c) => c.text)
|
|
27
29
|
.join('');
|
|
28
30
|
}
|
|
@@ -32,6 +34,120 @@ function extractText(msg) {
|
|
|
32
34
|
}
|
|
33
35
|
return '';
|
|
34
36
|
}
|
|
37
|
+
// --- MEDIA: inline resolution ---
|
|
38
|
+
const MEDIA_PREFIX = 'MEDIA:';
|
|
39
|
+
const MAX_INLINE_SIZE = 10 * 1024 * 1024; // 10 MB
|
|
40
|
+
const IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg']);
|
|
41
|
+
function mimeFromExt(ext) {
|
|
42
|
+
const map = {
|
|
43
|
+
'.png': 'image/png',
|
|
44
|
+
'.jpg': 'image/jpeg',
|
|
45
|
+
'.jpeg': 'image/jpeg',
|
|
46
|
+
'.gif': 'image/gif',
|
|
47
|
+
'.webp': 'image/webp',
|
|
48
|
+
'.svg': 'image/svg+xml',
|
|
49
|
+
'.pdf': 'application/pdf',
|
|
50
|
+
'.txt': 'text/plain',
|
|
51
|
+
'.json': 'application/json',
|
|
52
|
+
'.csv': 'text/csv',
|
|
53
|
+
};
|
|
54
|
+
return map[ext.toLowerCase()] ?? 'application/octet-stream';
|
|
55
|
+
}
|
|
56
|
+
function isImageExt(ext) {
|
|
57
|
+
return IMAGE_EXTENSIONS.has(ext.toLowerCase());
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Try to read a local file and return an inline content block (image or file).
|
|
61
|
+
* Returns null if the file doesn't exist, is too large, or is empty.
|
|
62
|
+
*/
|
|
63
|
+
function tryInlineFile(filePath) {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs.existsSync(filePath))
|
|
66
|
+
return null;
|
|
67
|
+
const stat = fs.statSync(filePath);
|
|
68
|
+
if (stat.size > MAX_INLINE_SIZE || stat.size === 0)
|
|
69
|
+
return null;
|
|
70
|
+
const ext = path.extname(filePath);
|
|
71
|
+
const mimeType = mimeFromExt(ext);
|
|
72
|
+
const data = fs.readFileSync(filePath);
|
|
73
|
+
const base64 = data.toString('base64');
|
|
74
|
+
if (isImageExt(ext)) {
|
|
75
|
+
return {
|
|
76
|
+
type: 'image',
|
|
77
|
+
source: {
|
|
78
|
+
type: 'base64',
|
|
79
|
+
media_type: mimeType,
|
|
80
|
+
data: base64,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Non-image files: return as a downloadable file block
|
|
85
|
+
return {
|
|
86
|
+
type: 'file',
|
|
87
|
+
name: path.basename(filePath),
|
|
88
|
+
mimeType,
|
|
89
|
+
data: base64,
|
|
90
|
+
size: stat.size,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Process content blocks: resolve MEDIA: text references to inline base64 blocks.
|
|
99
|
+
* - Text block with "MEDIA:/path/to/file.png" → replaced with image/file block
|
|
100
|
+
* - Text block with "MEDIA:/path" mixed with other text → MEDIA part extracted, rest stays as text
|
|
101
|
+
*/
|
|
102
|
+
export function resolveMediaBlocks(blocks) {
|
|
103
|
+
const resolved = [];
|
|
104
|
+
for (const block of blocks) {
|
|
105
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
106
|
+
const text = block.text.trim();
|
|
107
|
+
// Entire text block is a single MEDIA reference
|
|
108
|
+
if (text.startsWith(MEDIA_PREFIX) && !text.includes('\n')) {
|
|
109
|
+
const filePath = text.slice(MEDIA_PREFIX.length).trim();
|
|
110
|
+
const inlined = tryInlineFile(filePath);
|
|
111
|
+
if (inlined) {
|
|
112
|
+
resolved.push(inlined);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Check for MEDIA: references within multi-line text
|
|
117
|
+
if (text.includes(MEDIA_PREFIX)) {
|
|
118
|
+
const lines = text.split('\n');
|
|
119
|
+
const textLines = [];
|
|
120
|
+
for (const line of lines) {
|
|
121
|
+
const trimmed = line.trim();
|
|
122
|
+
if (trimmed.startsWith(MEDIA_PREFIX)) {
|
|
123
|
+
// Flush accumulated text
|
|
124
|
+
if (textLines.length > 0) {
|
|
125
|
+
resolved.push({ type: 'text', text: textLines.join('\n') });
|
|
126
|
+
textLines.length = 0;
|
|
127
|
+
}
|
|
128
|
+
const filePath = trimmed.slice(MEDIA_PREFIX.length).trim();
|
|
129
|
+
const inlined = tryInlineFile(filePath);
|
|
130
|
+
if (inlined) {
|
|
131
|
+
resolved.push(inlined);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
textLines.push(line); // Keep original if can't inline
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
textLines.push(line);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (textLines.length > 0) {
|
|
142
|
+
resolved.push({ type: 'text', text: textLines.join('\n') });
|
|
143
|
+
}
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
resolved.push(block);
|
|
148
|
+
}
|
|
149
|
+
return resolved;
|
|
150
|
+
}
|
|
35
151
|
export class OpenclawGatewayAdapter {
|
|
36
152
|
client;
|
|
37
153
|
streamCallbacks = new Map();
|
|
@@ -68,11 +184,23 @@ export class OpenclawGatewayAdapter {
|
|
|
68
184
|
async getHistory(sessionKey, limit = 200) {
|
|
69
185
|
const result = await this.client.request('chat.history', { sessionKey, limit });
|
|
70
186
|
const messages = (result?.messages ?? [])
|
|
71
|
-
.filter((m) => m.role === 'user' || m.role === 'assistant')
|
|
187
|
+
.filter((m) => m.role === 'user' || m.role === 'assistant' || m.role === 'toolResult')
|
|
72
188
|
.map((m) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
189
|
+
// Preserve content as-is: string or array of content blocks
|
|
190
|
+
let content;
|
|
191
|
+
if (typeof m.content === 'string') {
|
|
192
|
+
content = m.content;
|
|
193
|
+
}
|
|
194
|
+
else if (Array.isArray(m.content)) {
|
|
195
|
+
content = m.content;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
content = '';
|
|
199
|
+
}
|
|
200
|
+
// Resolve MEDIA: file references to inline base64
|
|
201
|
+
if (Array.isArray(content)) {
|
|
202
|
+
content = resolveMediaBlocks(content);
|
|
203
|
+
}
|
|
76
204
|
return {
|
|
77
205
|
role: m.role,
|
|
78
206
|
content,
|
|
@@ -81,12 +209,16 @@ export class OpenclawGatewayAdapter {
|
|
|
81
209
|
: m.timestamp ?? new Date().toISOString(),
|
|
82
210
|
};
|
|
83
211
|
});
|
|
84
|
-
// Deduplicate consecutive assistant messages with same content
|
|
212
|
+
// Deduplicate consecutive assistant messages with same text content
|
|
85
213
|
return messages.filter((msg, i) => {
|
|
86
214
|
if (i === 0)
|
|
87
215
|
return true;
|
|
88
216
|
const prev = messages[i - 1];
|
|
89
|
-
|
|
217
|
+
const prevText = typeof prev.content === 'string' ? prev.content
|
|
218
|
+
: prev.content.filter(b => b.type === 'text').map(b => b.text).join('');
|
|
219
|
+
const curText = typeof msg.content === 'string' ? msg.content
|
|
220
|
+
: msg.content.filter(b => b.type === 'text').map(b => b.text).join('');
|
|
221
|
+
return !(msg.role === 'assistant' && prev.role === 'assistant' && curText === prevText);
|
|
90
222
|
});
|
|
91
223
|
}
|
|
92
224
|
async sendMessage(params) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/providers/openclaw/gateway-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/providers/openclaw/gateway-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,10 +10,15 @@ export declare class GatewayClient {
|
|
|
10
10
|
private connected;
|
|
11
11
|
private token;
|
|
12
12
|
private url;
|
|
13
|
+
private reconnecting;
|
|
14
|
+
private destroyed;
|
|
15
|
+
private reconnectAttempts;
|
|
16
|
+
private static MAX_RECONNECT_DELAY;
|
|
13
17
|
constructor(url: string, token: string);
|
|
14
18
|
setEventHandler(handler: EventHandler): void;
|
|
15
19
|
connect(): Promise<void>;
|
|
16
20
|
disconnect(): void;
|
|
21
|
+
private scheduleReconnect;
|
|
17
22
|
isConnected(): boolean;
|
|
18
23
|
request(method: string, params: unknown): Promise<unknown>;
|
|
19
24
|
private handleMessage;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
2
|
import { randomUUID } from 'crypto';
|
|
3
|
+
import { loadOrCreateDeviceIdentity, publicKeyRawBase64Url, signPayload, buildDeviceAuthPayloadV3 } from './device-identity.js';
|
|
3
4
|
export class GatewayClient {
|
|
4
5
|
ws = null;
|
|
5
6
|
pending = new Map();
|
|
@@ -7,6 +8,10 @@ export class GatewayClient {
|
|
|
7
8
|
connected = false;
|
|
8
9
|
token;
|
|
9
10
|
url;
|
|
11
|
+
reconnecting = false;
|
|
12
|
+
destroyed = false;
|
|
13
|
+
reconnectAttempts = 0;
|
|
14
|
+
static MAX_RECONNECT_DELAY = 60_000;
|
|
10
15
|
constructor(url, token) {
|
|
11
16
|
this.url = url;
|
|
12
17
|
this.token = token;
|
|
@@ -16,9 +21,10 @@ export class GatewayClient {
|
|
|
16
21
|
}
|
|
17
22
|
connect() {
|
|
18
23
|
// RACE-5: guard against double-call before the first handshake completes
|
|
19
|
-
if (this.ws !== null) {
|
|
24
|
+
if (this.ws !== null && this.ws.readyState !== WebSocket.CLOSED) {
|
|
20
25
|
return Promise.reject(new Error('Already connecting or connected'));
|
|
21
26
|
}
|
|
27
|
+
this.ws = null;
|
|
22
28
|
return new Promise((resolve, reject) => {
|
|
23
29
|
this.ws = new WebSocket(this.url);
|
|
24
30
|
this.ws.on('open', () => {
|
|
@@ -37,7 +43,9 @@ export class GatewayClient {
|
|
|
37
43
|
});
|
|
38
44
|
this.ws.on('close', () => {
|
|
39
45
|
this.connected = false;
|
|
46
|
+
this.ws = null;
|
|
40
47
|
this.flushPending(new Error('Connection closed'));
|
|
48
|
+
this.scheduleReconnect();
|
|
41
49
|
});
|
|
42
50
|
// LEAK-3: store and clear the connect timeout after successful auth
|
|
43
51
|
const connectTimer = setTimeout(() => {
|
|
@@ -49,10 +57,37 @@ export class GatewayClient {
|
|
|
49
57
|
this.onEvent = async (ev) => {
|
|
50
58
|
if (ev.event === 'connect.challenge') {
|
|
51
59
|
try {
|
|
60
|
+
const challengePayload = ev.payload;
|
|
61
|
+
const nonce = challengePayload?.nonce ?? '';
|
|
62
|
+
const identity = loadOrCreateDeviceIdentity();
|
|
63
|
+
const signedAtMs = Date.now();
|
|
64
|
+
const scopes = ['operator.admin'];
|
|
65
|
+
const role = 'operator';
|
|
66
|
+
const payloadStr = buildDeviceAuthPayloadV3({
|
|
67
|
+
deviceId: identity.deviceId,
|
|
68
|
+
clientId: 'gateway-client',
|
|
69
|
+
clientMode: 'backend',
|
|
70
|
+
role,
|
|
71
|
+
scopes,
|
|
72
|
+
signedAtMs,
|
|
73
|
+
token: this.token,
|
|
74
|
+
nonce,
|
|
75
|
+
platform: process.platform,
|
|
76
|
+
deviceFamily: '',
|
|
77
|
+
});
|
|
78
|
+
const signature = signPayload(identity.privateKeyPem, payloadStr);
|
|
52
79
|
await this.request('connect', {
|
|
53
80
|
auth: { token: this.token },
|
|
54
|
-
scopes
|
|
81
|
+
scopes,
|
|
82
|
+
role,
|
|
55
83
|
caps: [],
|
|
84
|
+
device: {
|
|
85
|
+
id: identity.deviceId,
|
|
86
|
+
publicKey: publicKeyRawBase64Url(identity.publicKeyPem),
|
|
87
|
+
signature,
|
|
88
|
+
signedAt: signedAtMs,
|
|
89
|
+
nonce,
|
|
90
|
+
},
|
|
56
91
|
client: {
|
|
57
92
|
id: 'gateway-client',
|
|
58
93
|
displayName: 'Agent Controller',
|
|
@@ -77,11 +112,33 @@ export class GatewayClient {
|
|
|
77
112
|
});
|
|
78
113
|
}
|
|
79
114
|
disconnect() {
|
|
115
|
+
this.destroyed = true;
|
|
80
116
|
this.ws?.close();
|
|
81
117
|
this.ws = null;
|
|
82
118
|
this.connected = false;
|
|
83
119
|
this.flushPending(new Error('Disconnected'));
|
|
84
120
|
}
|
|
121
|
+
scheduleReconnect() {
|
|
122
|
+
if (this.destroyed || this.reconnecting)
|
|
123
|
+
return;
|
|
124
|
+
this.reconnecting = true;
|
|
125
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), GatewayClient.MAX_RECONNECT_DELAY);
|
|
126
|
+
this.reconnectAttempts++;
|
|
127
|
+
console.log(`[gateway-client] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})...`);
|
|
128
|
+
setTimeout(async () => {
|
|
129
|
+
this.reconnecting = false;
|
|
130
|
+
if (this.destroyed)
|
|
131
|
+
return;
|
|
132
|
+
try {
|
|
133
|
+
await this.connect();
|
|
134
|
+
this.reconnectAttempts = 0;
|
|
135
|
+
console.log('[gateway-client] Reconnected to gateway');
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
console.error('[gateway-client] Reconnect failed:', err instanceof Error ? err.message : err);
|
|
139
|
+
}
|
|
140
|
+
}, delay);
|
|
141
|
+
}
|
|
85
142
|
isConnected() {
|
|
86
143
|
return this.connected && this.ws?.readyState === WebSocket.OPEN;
|
|
87
144
|
}
|