@openclaw-cloud/agent-controller 0.13.0 → 0.14.0
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/handlers/board-handler.d.ts +1 -1
- package/dist/handlers/board-handler.js +54 -18
- package/dist/handlers/board-handler.js.map +1 -1
- package/dist/handlers/chat.js +4 -4
- package/dist/handlers/chat.js.map +1 -1
- package/dist/handlers/deploy.js +46 -42
- package/dist/handlers/deploy.js.map +1 -1
- package/dist/handlers/update-auth-profiles.js +10 -4
- package/dist/handlers/update-auth-profiles.js.map +1 -1
- package/dist/heartbeat.js +12 -15
- package/dist/heartbeat.js.map +1 -1
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/dist/openclaw/gateway-adapter.d.ts +5 -23
- package/dist/openclaw/gateway-adapter.js +3 -178
- package/dist/openclaw/gateway-adapter.js.map +1 -1
- package/dist/openclaw/index.d.ts +10 -9
- package/dist/openclaw/index.js +19 -61
- package/dist/openclaw/index.js.map +1 -1
- package/dist/openclaw/types.d.ts +5 -37
- package/dist/providers/chat-types.d.ts +39 -0
- package/dist/providers/chat-types.js +6 -0
- package/dist/providers/chat-types.js.map +1 -0
- package/dist/providers/index.d.ts +11 -0
- package/dist/providers/index.js +26 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/mock/index.d.ts +25 -0
- package/dist/providers/mock/index.js +40 -0
- package/dist/providers/mock/index.js.map +1 -0
- package/dist/providers/openclaw/gateway-adapter.d.ts +24 -0
- package/dist/providers/openclaw/gateway-adapter.js +181 -0
- package/dist/providers/openclaw/gateway-adapter.js.map +1 -0
- package/dist/providers/openclaw/gateway-client.d.ts +21 -0
- package/dist/providers/openclaw/gateway-client.js +138 -0
- package/dist/providers/openclaw/gateway-client.js.map +1 -0
- package/dist/providers/openclaw/index.d.ts +21 -0
- package/dist/providers/openclaw/index.js +120 -0
- package/dist/providers/openclaw/index.js.map +1 -0
- package/dist/providers/types.d.ts +38 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/utils/gateway-restart.d.ts +7 -4
- package/dist/utils/gateway-restart.js +15 -19
- package/dist/utils/gateway-restart.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { GatewayClient } from './gateway-client.js';
|
|
2
|
+
import { toErrorMessage } from '../../utils/response.js';
|
|
3
|
+
const STREAM_TTL = 300_000; // 5 min
|
|
4
|
+
/**
|
|
5
|
+
* Extract plain text from gateway message payload.
|
|
6
|
+
* Supports:
|
|
7
|
+
* - string: "hello"
|
|
8
|
+
* - content array: [{type:"text", text:"hello"}]
|
|
9
|
+
* - message object: {role, content: [{type:"text", text:"hello"}], timestamp}
|
|
10
|
+
*/
|
|
11
|
+
function extractText(msg) {
|
|
12
|
+
if (typeof msg === 'string')
|
|
13
|
+
return msg;
|
|
14
|
+
if (Array.isArray(msg)) {
|
|
15
|
+
return msg
|
|
16
|
+
.filter((c) => c.type === 'text')
|
|
17
|
+
.map((c) => c.text)
|
|
18
|
+
.join('');
|
|
19
|
+
}
|
|
20
|
+
if (typeof msg === 'object' && msg !== null) {
|
|
21
|
+
const obj = msg;
|
|
22
|
+
// {role, content: [...], timestamp} format
|
|
23
|
+
if (Array.isArray(obj['content'])) {
|
|
24
|
+
return obj['content']
|
|
25
|
+
.filter((c) => c.type === 'text')
|
|
26
|
+
.map((c) => c.text)
|
|
27
|
+
.join('');
|
|
28
|
+
}
|
|
29
|
+
// {text: "..."} shorthand
|
|
30
|
+
if (typeof obj['text'] === 'string')
|
|
31
|
+
return obj['text'];
|
|
32
|
+
}
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
export class OpenclawGatewayAdapter {
|
|
36
|
+
client;
|
|
37
|
+
streamCallbacks = new Map();
|
|
38
|
+
constructor(url, token) {
|
|
39
|
+
this.client = new GatewayClient(url, token);
|
|
40
|
+
this.client.setEventHandler(this.handleEvent.bind(this));
|
|
41
|
+
}
|
|
42
|
+
async connect() {
|
|
43
|
+
await this.client.connect();
|
|
44
|
+
}
|
|
45
|
+
disconnect() {
|
|
46
|
+
// Notify all in-flight streams before closing
|
|
47
|
+
for (const [, cb] of this.streamCallbacks) {
|
|
48
|
+
clearTimeout(cb.timer);
|
|
49
|
+
cb.onError?.('Connection closed');
|
|
50
|
+
}
|
|
51
|
+
this.streamCallbacks.clear();
|
|
52
|
+
this.client.disconnect();
|
|
53
|
+
}
|
|
54
|
+
isConnected() {
|
|
55
|
+
return this.client.isConnected();
|
|
56
|
+
}
|
|
57
|
+
async listSessions() {
|
|
58
|
+
const result = await this.client.request('sessions.list', {});
|
|
59
|
+
return (result?.sessions ?? []).map((s) => ({
|
|
60
|
+
key: s.key,
|
|
61
|
+
sessionId: s.sessionId ?? '',
|
|
62
|
+
kind: s.kind ?? 'direct',
|
|
63
|
+
label: s.key.split(':').pop() ?? s.key,
|
|
64
|
+
updatedAt: s.updatedAt ?? 0,
|
|
65
|
+
model: s.model,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
async getHistory(sessionKey, limit = 200) {
|
|
69
|
+
const result = await this.client.request('chat.history', { sessionKey, limit });
|
|
70
|
+
const messages = (result?.messages ?? [])
|
|
71
|
+
.filter((m) => m.role === 'user' || m.role === 'assistant')
|
|
72
|
+
.map((m) => {
|
|
73
|
+
const content = Array.isArray(m.content)
|
|
74
|
+
? m.content.filter((c) => c.type === 'text').map((c) => c.text).join('')
|
|
75
|
+
: String(m.content ?? '');
|
|
76
|
+
return {
|
|
77
|
+
role: m.role,
|
|
78
|
+
content,
|
|
79
|
+
timestamp: typeof m.timestamp === 'number'
|
|
80
|
+
? new Date(m.timestamp).toISOString()
|
|
81
|
+
: m.timestamp ?? new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
// Deduplicate consecutive assistant messages with same content
|
|
85
|
+
return messages.filter((msg, i) => {
|
|
86
|
+
if (i === 0)
|
|
87
|
+
return true;
|
|
88
|
+
const prev = messages[i - 1];
|
|
89
|
+
return !(msg.role === 'assistant' && prev.role === 'assistant' && msg.content === prev.content);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async sendMessage(params) {
|
|
93
|
+
const key = params.idempotencyKey;
|
|
94
|
+
// TTL timer: if no final/error event arrives within 5 min, clean up and error
|
|
95
|
+
const timer = setTimeout(() => {
|
|
96
|
+
const cb = this.streamCallbacks.get(key);
|
|
97
|
+
if (cb) {
|
|
98
|
+
this.streamCallbacks.delete(key);
|
|
99
|
+
cb.onError?.('Stream timeout');
|
|
100
|
+
}
|
|
101
|
+
}, STREAM_TTL);
|
|
102
|
+
// Register stream callbacks BEFORE sending
|
|
103
|
+
this.streamCallbacks.set(key, {
|
|
104
|
+
onDelta: params.onDelta,
|
|
105
|
+
onDone: params.onDone,
|
|
106
|
+
onError: params.onError,
|
|
107
|
+
lastText: '',
|
|
108
|
+
timer,
|
|
109
|
+
});
|
|
110
|
+
const payload = {
|
|
111
|
+
sessionKey: params.sessionKey,
|
|
112
|
+
message: params.text,
|
|
113
|
+
deliver: false,
|
|
114
|
+
idempotencyKey: key,
|
|
115
|
+
};
|
|
116
|
+
if (params.attachments?.length) {
|
|
117
|
+
payload['attachments'] = params.attachments;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
await this.client.request('chat.send', payload);
|
|
121
|
+
// Request accepted — response comes via events
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
const cb = this.streamCallbacks.get(key);
|
|
125
|
+
if (cb) {
|
|
126
|
+
clearTimeout(cb.timer);
|
|
127
|
+
this.streamCallbacks.delete(key);
|
|
128
|
+
}
|
|
129
|
+
params.onError?.(toErrorMessage(err));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async abort(sessionKey, runId) {
|
|
133
|
+
await this.client.request('chat.abort', { sessionKey, runId }).catch(() => { });
|
|
134
|
+
}
|
|
135
|
+
deleteStream(runId) {
|
|
136
|
+
const cb = this.streamCallbacks.get(runId);
|
|
137
|
+
if (cb) {
|
|
138
|
+
clearTimeout(cb.timer);
|
|
139
|
+
this.streamCallbacks.delete(runId);
|
|
140
|
+
}
|
|
141
|
+
return cb;
|
|
142
|
+
}
|
|
143
|
+
handleEvent(event) {
|
|
144
|
+
console.log('[chat] Gateway event:', event.event, JSON.stringify(event.payload).slice(0, 500));
|
|
145
|
+
const data = event.payload;
|
|
146
|
+
if (!data || !data['sessionKey'])
|
|
147
|
+
return;
|
|
148
|
+
// Stream events have runId matching idempotencyKey
|
|
149
|
+
const runId = data['runId'];
|
|
150
|
+
const cb = runId ? this.streamCallbacks.get(runId) : null;
|
|
151
|
+
if (!cb)
|
|
152
|
+
return;
|
|
153
|
+
if (data['state'] === 'delta' && data['message'] != null) {
|
|
154
|
+
const msg = data['message'];
|
|
155
|
+
const text = extractText(msg);
|
|
156
|
+
console.log('[chat] delta extracted:', text.slice(0, 100));
|
|
157
|
+
cb.lastText = text;
|
|
158
|
+
cb.onDelta?.(text);
|
|
159
|
+
}
|
|
160
|
+
else if (data['state'] === 'final') {
|
|
161
|
+
const finalMsg = data['message'];
|
|
162
|
+
const finalText = finalMsg ? extractText(finalMsg) : cb.lastText;
|
|
163
|
+
console.log('[chat] final text:', finalText.slice(0, 100), 'lastText:', cb.lastText.slice(0, 100));
|
|
164
|
+
this.deleteStream(runId);
|
|
165
|
+
cb.onDone?.(finalText || cb.lastText);
|
|
166
|
+
}
|
|
167
|
+
else if (data['state'] === 'aborted') {
|
|
168
|
+
this.deleteStream(runId);
|
|
169
|
+
cb.onDone?.(cb.lastText); // still send whatever we have
|
|
170
|
+
}
|
|
171
|
+
else if (data['state'] === 'error') {
|
|
172
|
+
this.deleteStream(runId);
|
|
173
|
+
const errData = data['error'];
|
|
174
|
+
const errMsg = typeof errData === 'string'
|
|
175
|
+
? errData
|
|
176
|
+
: errData?.message ?? 'Unknown error';
|
|
177
|
+
cb.onError?.(errMsg);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=gateway-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/providers/openclaw/gateway-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type EventHandler = (event: {
|
|
2
|
+
event: string;
|
|
3
|
+
payload: unknown;
|
|
4
|
+
seq?: number;
|
|
5
|
+
}) => void;
|
|
6
|
+
export declare class GatewayClient {
|
|
7
|
+
private ws;
|
|
8
|
+
private pending;
|
|
9
|
+
private onEvent;
|
|
10
|
+
private connected;
|
|
11
|
+
private token;
|
|
12
|
+
private url;
|
|
13
|
+
constructor(url: string, token: string);
|
|
14
|
+
setEventHandler(handler: EventHandler): void;
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
disconnect(): void;
|
|
17
|
+
isConnected(): boolean;
|
|
18
|
+
request(method: string, params: unknown): Promise<unknown>;
|
|
19
|
+
private handleMessage;
|
|
20
|
+
private flushPending;
|
|
21
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
export class GatewayClient {
|
|
4
|
+
ws = null;
|
|
5
|
+
pending = new Map();
|
|
6
|
+
onEvent = null;
|
|
7
|
+
connected = false;
|
|
8
|
+
token;
|
|
9
|
+
url;
|
|
10
|
+
constructor(url, token) {
|
|
11
|
+
this.url = url;
|
|
12
|
+
this.token = token;
|
|
13
|
+
}
|
|
14
|
+
setEventHandler(handler) {
|
|
15
|
+
this.onEvent = handler;
|
|
16
|
+
}
|
|
17
|
+
connect() {
|
|
18
|
+
// RACE-5: guard against double-call before the first handshake completes
|
|
19
|
+
if (this.ws !== null) {
|
|
20
|
+
return Promise.reject(new Error('Already connecting or connected'));
|
|
21
|
+
}
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
this.ws = new WebSocket(this.url);
|
|
24
|
+
this.ws.on('open', () => {
|
|
25
|
+
// Wait for connect.challenge event, then authenticate
|
|
26
|
+
});
|
|
27
|
+
this.ws.on('message', (raw) => {
|
|
28
|
+
try {
|
|
29
|
+
const msg = JSON.parse(raw.toString());
|
|
30
|
+
this.handleMessage(msg);
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
});
|
|
34
|
+
this.ws.on('error', (e) => {
|
|
35
|
+
if (!this.connected)
|
|
36
|
+
reject(e);
|
|
37
|
+
});
|
|
38
|
+
this.ws.on('close', () => {
|
|
39
|
+
this.connected = false;
|
|
40
|
+
this.flushPending(new Error('Connection closed'));
|
|
41
|
+
});
|
|
42
|
+
// LEAK-3: store and clear the connect timeout after successful auth
|
|
43
|
+
const connectTimer = setTimeout(() => {
|
|
44
|
+
if (!this.connected)
|
|
45
|
+
reject(new Error('Connect timeout'));
|
|
46
|
+
}, 10_000);
|
|
47
|
+
// Wait for connect.challenge → authenticate → resolve
|
|
48
|
+
const origHandler = this.onEvent;
|
|
49
|
+
this.onEvent = async (ev) => {
|
|
50
|
+
if (ev.event === 'connect.challenge') {
|
|
51
|
+
try {
|
|
52
|
+
await this.request('connect', {
|
|
53
|
+
auth: { token: this.token },
|
|
54
|
+
scopes: ['operator.admin'],
|
|
55
|
+
caps: [],
|
|
56
|
+
client: {
|
|
57
|
+
id: 'gateway-client',
|
|
58
|
+
displayName: 'Agent Controller',
|
|
59
|
+
version: '1',
|
|
60
|
+
platform: process.platform,
|
|
61
|
+
mode: 'backend',
|
|
62
|
+
},
|
|
63
|
+
minProtocol: 3,
|
|
64
|
+
maxProtocol: 3,
|
|
65
|
+
});
|
|
66
|
+
this.connected = true;
|
|
67
|
+
clearTimeout(connectTimer);
|
|
68
|
+
this.onEvent = origHandler;
|
|
69
|
+
resolve();
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
clearTimeout(connectTimer);
|
|
73
|
+
reject(e);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
disconnect() {
|
|
80
|
+
this.ws?.close();
|
|
81
|
+
this.ws = null;
|
|
82
|
+
this.connected = false;
|
|
83
|
+
this.flushPending(new Error('Disconnected'));
|
|
84
|
+
}
|
|
85
|
+
isConnected() {
|
|
86
|
+
return this.connected && this.ws?.readyState === WebSocket.OPEN;
|
|
87
|
+
}
|
|
88
|
+
request(method, params) {
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
91
|
+
return reject(new Error('Not connected'));
|
|
92
|
+
}
|
|
93
|
+
const id = randomUUID();
|
|
94
|
+
// LEAK-2: store the per-request timeout so it can be cleared when the request resolves
|
|
95
|
+
const timer = setTimeout(() => {
|
|
96
|
+
if (this.pending.has(id)) {
|
|
97
|
+
this.pending.delete(id);
|
|
98
|
+
reject(new Error(`Request timeout: ${method}`));
|
|
99
|
+
}
|
|
100
|
+
}, 120_000);
|
|
101
|
+
this.pending.set(id, {
|
|
102
|
+
resolve: (payload) => { clearTimeout(timer); resolve(payload); },
|
|
103
|
+
reject: (err) => { clearTimeout(timer); reject(err); },
|
|
104
|
+
});
|
|
105
|
+
this.ws.send(JSON.stringify({ type: 'req', id, method, params }));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
handleMessage(msg) {
|
|
109
|
+
if (typeof msg !== 'object' || msg === null)
|
|
110
|
+
return;
|
|
111
|
+
const m = msg;
|
|
112
|
+
if (m['type'] === 'event') {
|
|
113
|
+
this.onEvent?.(m);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (m['type'] === 'res') {
|
|
117
|
+
const id = m['id'];
|
|
118
|
+
const req = this.pending.get(id);
|
|
119
|
+
if (!req)
|
|
120
|
+
return;
|
|
121
|
+
this.pending.delete(id);
|
|
122
|
+
if (m['ok']) {
|
|
123
|
+
req.resolve(m['payload']);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const errPayload = m['error'];
|
|
127
|
+
req.reject(new Error(errPayload?.message ?? 'Request failed'));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
flushPending(err) {
|
|
132
|
+
for (const [, req] of this.pending) {
|
|
133
|
+
req.reject(err);
|
|
134
|
+
}
|
|
135
|
+
this.pending.clear();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=gateway-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../../../src/providers/openclaw/gateway-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IAgentProvider, AgentHealthStatus, SendMessageParams } from '../types.js';
|
|
2
|
+
import type { ChatSession, ChatMessage } from '../chat-types.js';
|
|
3
|
+
export { OpenclawGatewayAdapter } from './gateway-adapter.js';
|
|
4
|
+
export declare class OpenclawProvider implements IAgentProvider {
|
|
5
|
+
readonly name = "openclaw";
|
|
6
|
+
private adapter;
|
|
7
|
+
private wsUrl;
|
|
8
|
+
private wsToken;
|
|
9
|
+
private _connecting;
|
|
10
|
+
constructor(wsUrl: string, wsToken: string);
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
disconnect(): void;
|
|
13
|
+
isConnected(): boolean;
|
|
14
|
+
sendMessage(params: SendMessageParams): Promise<void>;
|
|
15
|
+
listSessions(): Promise<ChatSession[]>;
|
|
16
|
+
getHistory(sessionKey: string, limit?: number): Promise<ChatMessage[]>;
|
|
17
|
+
abort(sessionKey: string, runId?: string): Promise<void>;
|
|
18
|
+
healthCheck(): Promise<AgentHealthStatus>;
|
|
19
|
+
restart(): Promise<void>;
|
|
20
|
+
install(currentVersion?: string): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { OpenclawGatewayAdapter } from './gateway-adapter.js';
|
|
2
|
+
import { execAsync } from '../../utils/exec.js';
|
|
3
|
+
export { OpenclawGatewayAdapter } from './gateway-adapter.js';
|
|
4
|
+
export class OpenclawProvider {
|
|
5
|
+
name = 'openclaw';
|
|
6
|
+
adapter = null;
|
|
7
|
+
wsUrl;
|
|
8
|
+
wsToken;
|
|
9
|
+
_connecting = null;
|
|
10
|
+
constructor(wsUrl, wsToken) {
|
|
11
|
+
this.wsUrl = wsUrl;
|
|
12
|
+
this.wsToken = wsToken;
|
|
13
|
+
}
|
|
14
|
+
async connect() {
|
|
15
|
+
if (this.adapter?.isConnected())
|
|
16
|
+
return;
|
|
17
|
+
// Guard against concurrent connect calls
|
|
18
|
+
if (this._connecting) {
|
|
19
|
+
await this._connecting;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
this._connecting = (async () => {
|
|
23
|
+
const maxRetries = 5;
|
|
24
|
+
const baseDelayMs = 2000;
|
|
25
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
26
|
+
try {
|
|
27
|
+
this.adapter = new OpenclawGatewayAdapter(this.wsUrl, this.wsToken);
|
|
28
|
+
await this.adapter.connect();
|
|
29
|
+
console.log(`OpenClaw Gateway WS connected (attempt ${attempt})`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
34
|
+
console.warn(`Chat provider connect failed (attempt ${attempt}/${maxRetries}): ${msg}`);
|
|
35
|
+
this.adapter?.disconnect();
|
|
36
|
+
this.adapter = null;
|
|
37
|
+
if (attempt < maxRetries) {
|
|
38
|
+
await new Promise((r) => setTimeout(r, baseDelayMs * Math.min(attempt, 5)));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
throw new Error('OpenclawProvider: connect exhausted');
|
|
43
|
+
})();
|
|
44
|
+
try {
|
|
45
|
+
await this._connecting;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
this._connecting = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
disconnect() {
|
|
52
|
+
this.adapter?.disconnect();
|
|
53
|
+
this.adapter = null;
|
|
54
|
+
this._connecting = null;
|
|
55
|
+
}
|
|
56
|
+
isConnected() {
|
|
57
|
+
return this.adapter?.isConnected() ?? false;
|
|
58
|
+
}
|
|
59
|
+
// === Chat — delegate to gateway adapter ===
|
|
60
|
+
async sendMessage(params) {
|
|
61
|
+
if (!this.adapter) {
|
|
62
|
+
// Lazy connect
|
|
63
|
+
await this.connect();
|
|
64
|
+
}
|
|
65
|
+
if (!this.adapter)
|
|
66
|
+
throw new Error('Provider not connected');
|
|
67
|
+
await this.adapter.sendMessage(params);
|
|
68
|
+
}
|
|
69
|
+
async listSessions() {
|
|
70
|
+
if (!this.adapter)
|
|
71
|
+
return [];
|
|
72
|
+
return this.adapter.listSessions();
|
|
73
|
+
}
|
|
74
|
+
async getHistory(sessionKey, limit) {
|
|
75
|
+
if (!this.adapter)
|
|
76
|
+
return [];
|
|
77
|
+
return this.adapter.getHistory(sessionKey, limit);
|
|
78
|
+
}
|
|
79
|
+
async abort(sessionKey, runId) {
|
|
80
|
+
await this.adapter?.abort(sessionKey, runId);
|
|
81
|
+
}
|
|
82
|
+
// === Infrastructure ===
|
|
83
|
+
async healthCheck() {
|
|
84
|
+
try {
|
|
85
|
+
const output = await execAsync('openclaw health --json', 5000);
|
|
86
|
+
const parsed = JSON.parse(output);
|
|
87
|
+
const running = parsed.ok === true;
|
|
88
|
+
return { ok: running, rpcOk: running };
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return { ok: false, rpcOk: false };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async restart() {
|
|
95
|
+
const { exec } = await import('node:child_process');
|
|
96
|
+
return new Promise((resolve) => {
|
|
97
|
+
exec('openclaw gateway restart', { timeout: 30_000 }, (error) => {
|
|
98
|
+
if (error)
|
|
99
|
+
console.error('Gateway restart failed:', error.message);
|
|
100
|
+
else
|
|
101
|
+
console.log('Gateway restarted');
|
|
102
|
+
resolve(); // always resolve — caller decides how to handle
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async install(currentVersion) {
|
|
107
|
+
const { exec } = await import('node:child_process');
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
exec('npm i -g openclaw', { timeout: 120_000 }, (error, stdout, stderr) => {
|
|
110
|
+
if (error) {
|
|
111
|
+
reject(Object.assign(error, { stdout: stdout.toString(), stderr: stderr.toString() }));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
resolve();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/openclaw/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ChatSession, ChatMessage, ChatAttachment } from './chat-types.js';
|
|
2
|
+
export type { ChatSession, ChatMessage, ChatAttachment };
|
|
3
|
+
export interface AgentHealthStatus {
|
|
4
|
+
ok: boolean;
|
|
5
|
+
rpcOk: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface SendMessageParams {
|
|
8
|
+
sessionKey: string;
|
|
9
|
+
text: string;
|
|
10
|
+
idempotencyKey: string;
|
|
11
|
+
attachments?: ChatAttachment[];
|
|
12
|
+
onDelta?: (accumulatedText: string) => void;
|
|
13
|
+
onDone?: (finalText: string) => void;
|
|
14
|
+
onError?: (error: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface IAgentProvider {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** Initialize/connect the provider */
|
|
19
|
+
connect(): Promise<void>;
|
|
20
|
+
/** Disconnect/cleanup */
|
|
21
|
+
disconnect(): void;
|
|
22
|
+
/** Is provider connected and ready? */
|
|
23
|
+
isConnected(): boolean;
|
|
24
|
+
/** Send a message to the agent (task prompt, chat message, etc.) */
|
|
25
|
+
sendMessage(params: SendMessageParams): Promise<void>;
|
|
26
|
+
/** List active chat sessions */
|
|
27
|
+
listSessions(): Promise<ChatSession[]>;
|
|
28
|
+
/** Get chat history for a session */
|
|
29
|
+
getHistory(sessionKey: string, limit?: number): Promise<ChatMessage[]>;
|
|
30
|
+
/** Abort an in-flight message */
|
|
31
|
+
abort(sessionKey: string, runId?: string): Promise<void>;
|
|
32
|
+
/** Check if the agent runtime is healthy */
|
|
33
|
+
healthCheck(): Promise<AgentHealthStatus>;
|
|
34
|
+
/** Restart the agent runtime */
|
|
35
|
+
restart(): Promise<void>;
|
|
36
|
+
/** Install/update the agent runtime */
|
|
37
|
+
install(currentVersion?: string): Promise<void>;
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
|
package/dist/types.d.ts
CHANGED
|
@@ -88,8 +88,14 @@ export interface CardDetail {
|
|
|
88
88
|
assignedAgentId?: string | null;
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
+
export interface MockAction {
|
|
92
|
+
type: 'wait' | 'artifact' | 'comment' | 'result' | 'move';
|
|
93
|
+
ms?: number;
|
|
94
|
+
body?: Record<string, unknown>;
|
|
95
|
+
}
|
|
91
96
|
export interface TaskInfo {
|
|
92
97
|
cardProcessingId: string;
|
|
93
98
|
prompt: string;
|
|
94
99
|
workflowSteps: Array<Record<string, unknown>>;
|
|
100
|
+
mockActions?: MockAction[];
|
|
95
101
|
}
|
|
@@ -3,8 +3,11 @@ export interface GatewayRestartResult {
|
|
|
3
3
|
stderr: string;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Rejects with an Error that also has stdout/stderr properties on failure.
|
|
6
|
+
* Restart the gateway via the configured agent provider.
|
|
7
|
+
* Returns { stdout: '', stderr: '' } for interface compatibility.
|
|
9
8
|
*/
|
|
10
|
-
export declare function
|
|
9
|
+
export declare function restartGateway(): Promise<GatewayRestartResult>;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use restartGateway() instead.
|
|
12
|
+
*/
|
|
13
|
+
export declare const execGatewayRestart: typeof restartGateway;
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getProvider } from '../providers/index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Rejects with an Error that also has stdout/stderr properties on failure.
|
|
3
|
+
* Restart the gateway via the configured agent provider.
|
|
4
|
+
* Returns { stdout: '', stderr: '' } for interface compatibility.
|
|
6
5
|
*/
|
|
7
|
-
export function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
reject(Object.assign(error, result));
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
resolve(result);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
});
|
|
6
|
+
export async function restartGateway() {
|
|
7
|
+
const provider = getProvider();
|
|
8
|
+
if (!provider) {
|
|
9
|
+
console.warn('No provider configured, cannot restart gateway');
|
|
10
|
+
return { stdout: '', stderr: '' };
|
|
11
|
+
}
|
|
12
|
+
await provider.restart();
|
|
13
|
+
return { stdout: '', stderr: '' };
|
|
22
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use restartGateway() instead.
|
|
17
|
+
*/
|
|
18
|
+
export const execGatewayRestart = restartGateway;
|
|
23
19
|
//# sourceMappingURL=gateway-restart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-restart.js","sourceRoot":"","sources":["../../src/utils/gateway-restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"gateway-restart.js","sourceRoot":"","sources":["../../src/utils/gateway-restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC/D,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC"}
|