@winmatrix/daemon 1.0.3 → 1.0.5
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/bin/winmatrix-daemon.js +3 -1
- package/dist/core/AgentProcessManager.d.ts +21 -2
- package/dist/core/AgentProcessManager.d.ts.map +1 -1
- package/dist/core/AgentProcessManager.js +351 -8
- package/dist/core/AgentProcessManager.js.map +1 -1
- package/dist/core/DaemonClient.d.ts +102 -0
- package/dist/core/DaemonClient.d.ts.map +1 -0
- package/dist/core/DaemonClient.js +225 -0
- package/dist/core/DaemonClient.js.map +1 -0
- package/dist/core/RuntimeDoctor.d.ts +1 -1
- package/dist/core/RuntimeDoctor.d.ts.map +1 -1
- package/dist/core/RuntimeDoctor.js +27 -2
- package/dist/core/RuntimeDoctor.js.map +1 -1
- package/dist/core/WinMatrixAgentClient.d.ts +183 -0
- package/dist/core/WinMatrixAgentClient.d.ts.map +1 -0
- package/dist/core/WinMatrixAgentClient.js +555 -0
- package/dist/core/WinMatrixAgentClient.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -11
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/core/RuntimeAvailabilityReporter.d.ts +0 -27
- package/dist/core/RuntimeAvailabilityReporter.d.ts.map +0 -1
- package/dist/core/RuntimeAvailabilityReporter.js +0 -79
- package/dist/core/RuntimeAvailabilityReporter.js.map +0 -1
- package/dist/wrapper/AgentProcessManager.d.ts +0 -80
- package/dist/wrapper/AgentProcessManager.d.ts.map +0 -1
- package/dist/wrapper/AgentProcessManager.js +0 -474
- package/dist/wrapper/AgentProcessManager.js.map +0 -1
- package/dist/wrapper/AgentWrapper.d.ts +0 -7
- package/dist/wrapper/AgentWrapper.d.ts.map +0 -1
- package/dist/wrapper/AgentWrapper.js +0 -229
- package/dist/wrapper/AgentWrapper.js.map +0 -1
- package/dist/wrapper/claudeCommand.d.ts +0 -2
- package/dist/wrapper/claudeCommand.d.ts.map +0 -1
- package/dist/wrapper/claudeCommand.js +0 -2
- package/dist/wrapper/claudeCommand.js.map +0 -1
- package/dist/wrapper/supportedAgentTypes.d.ts +0 -7
- package/dist/wrapper/supportedAgentTypes.d.ts.map +0 -1
- package/dist/wrapper/supportedAgentTypes.js +0 -6
- package/dist/wrapper/supportedAgentTypes.js.map +0 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WinMatrix Agent SDK - DaemonClient
|
|
3
|
+
*
|
|
4
|
+
* Extends WinMatrixAgentClient for the Computer/Daemon connection model.
|
|
5
|
+
* After WebSocket connection, sends `computer.register` (instead of `register`)
|
|
6
|
+
* with the computer's identity, host info, and detected runtimes.
|
|
7
|
+
*
|
|
8
|
+
* The Daemon connection acts as a multiplexing channel:
|
|
9
|
+
* - computer.heartbeat events keep the Computer alive
|
|
10
|
+
* - agent.create / agent.stop events manage Agent lifecycle on the host
|
|
11
|
+
* - task.* messages are routed by agentId for individual agents
|
|
12
|
+
*/
|
|
13
|
+
import { type AgentProfile, type ComputerRegisterParams, type ClientInboundFrame } from '@winmatrix/protocol';
|
|
14
|
+
import { WinMatrixAgentClient, type WinMatrixAgentClientOptions } from './WinMatrixAgentClient.js';
|
|
15
|
+
export interface DaemonClientOptions extends Omit<WinMatrixAgentClientOptions, 'agentId' | 'name' | 'agentType' | 'capabilities' | 'apiKey'> {
|
|
16
|
+
/** Persistent installation UUID */
|
|
17
|
+
installationId: string;
|
|
18
|
+
/** Computer registration token (wmc_...) */
|
|
19
|
+
token: string;
|
|
20
|
+
/** Operating system name + version (e.g. "darwin 24.0.0") */
|
|
21
|
+
hostOs: string;
|
|
22
|
+
/** CPU architecture (e.g. "arm64") */
|
|
23
|
+
hostArch: string;
|
|
24
|
+
/** Hostname of the machine */
|
|
25
|
+
hostname: string;
|
|
26
|
+
/** Daemon version string */
|
|
27
|
+
daemonVersion?: string;
|
|
28
|
+
/** Detected AI runtimes on this computer */
|
|
29
|
+
runtimes: ComputerRegisterParams['runtimes'];
|
|
30
|
+
/** Agent types the daemon can host natively (e.g. ["claude-code","hermes","openclaw"]) */
|
|
31
|
+
supportedAgentTypes?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Called for agent-level messages that should be forwarded to AgentWrapper
|
|
34
|
+
* rather than handled by the SDK client.
|
|
35
|
+
*
|
|
36
|
+
* @param frame - Parsed standard frame (event/req/res)
|
|
37
|
+
* @param raw - Raw JSON string for forwarding to Wrapper stdin
|
|
38
|
+
* @param agentId - Top-level agentId extracted from the raw JSON before parseFrame
|
|
39
|
+
*/
|
|
40
|
+
onPassthrough?: (frame: ClientInboundFrame, raw: string, agentId: string | null) => void;
|
|
41
|
+
}
|
|
42
|
+
export interface AgentCreateEvent {
|
|
43
|
+
agentId: string;
|
|
44
|
+
runtime: string;
|
|
45
|
+
apiKey: string;
|
|
46
|
+
name: string;
|
|
47
|
+
agentType: string;
|
|
48
|
+
}
|
|
49
|
+
export interface AgentStopEvent {
|
|
50
|
+
agentId: string;
|
|
51
|
+
}
|
|
52
|
+
export interface AgentErrorEvent {
|
|
53
|
+
agentId: string;
|
|
54
|
+
error: string;
|
|
55
|
+
}
|
|
56
|
+
type DaemonEventHandler<T = void> = (data: T) => void | Promise<void>;
|
|
57
|
+
export declare class DaemonClient extends WinMatrixAgentClient {
|
|
58
|
+
private readonly daemonOptions;
|
|
59
|
+
private serverComputerId;
|
|
60
|
+
private agentCreateHandler;
|
|
61
|
+
private agentStopHandler;
|
|
62
|
+
private profileCollector;
|
|
63
|
+
/** 心跳执行锁,防止定时器回调并发 */
|
|
64
|
+
private heartbeatInProgress;
|
|
65
|
+
constructor(options: DaemonClientOptions);
|
|
66
|
+
/** Register handler for daemon-specific events */
|
|
67
|
+
onDaemonEvent(event: 'agent.create' | 'agent.stop', handler: DaemonEventHandler<unknown>): void;
|
|
68
|
+
/** Get the server-assigned computer ID (available after successful registration) */
|
|
69
|
+
getComputerId(): string | null;
|
|
70
|
+
/** Set the profile collector function (called during heartbeat to attach agentProfiles) */
|
|
71
|
+
setProfileCollector(fn: () => Promise<AgentProfile[]>): void;
|
|
72
|
+
/**
|
|
73
|
+
* 通过 daemon 连接发送 agent.error 事件。
|
|
74
|
+
* 替代直接访问私有 ws 属性,用于 agent.create 失败时通知服务端。
|
|
75
|
+
*/
|
|
76
|
+
sendAgentError(agentId: string, error: string): boolean;
|
|
77
|
+
/** Immediately send a heartbeat with agent profiles (used for agent create/destroy/rescan) */
|
|
78
|
+
sendHeartbeatNow(): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Override register() to send computer.register instead of agent register.
|
|
81
|
+
*/
|
|
82
|
+
protected register(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Override heartbeat for daemon mode — sends computer.heartbeat events with optional agentProfiles.
|
|
85
|
+
* 使用锁防止定时器回调并发执行,确保上次心跳完成后再调度下次。
|
|
86
|
+
*/
|
|
87
|
+
protected startHeartbeat(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Override to extract agentId before parseFrame and intercept daemon events.
|
|
90
|
+
*
|
|
91
|
+
* 注意:方案 B 下 onPassthrough 未设置,passthrough 路由代码(task.assign ACK / wrapper 响应)
|
|
92
|
+
* 当前为 dead code。每个 agent 有独立 WinMatrixAgentClient + WebSocket,消息由
|
|
93
|
+
* AgentProcessManager 分发到各 agent 的 client,不经过 daemon 连接多路复用。
|
|
94
|
+
*/
|
|
95
|
+
protected handleMessage(data: import('ws').Data): void;
|
|
96
|
+
/**
|
|
97
|
+
* Handle daemon-specific events. Returns true if the event was handled.
|
|
98
|
+
*/
|
|
99
|
+
private handleDaemonEvent;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
|
102
|
+
//# sourceMappingURL=DaemonClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DaemonClient.d.ts","sourceRoot":"","sources":["../../src/core/DaemonClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAOL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAE3B,KAAK,kBAAkB,EAIxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAInG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,2BAA2B,EAAE,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,CAAC;IAC1I,mCAAmC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAC7C,0FAA0F;IAC1F,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC1F;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,KAAK,kBAAkB,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAItE,qBAAa,YAAa,SAAQ,oBAAoB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,kBAAkB,CAAqD;IAC/E,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,gBAAgB,CAAgD;IACxE,sBAAsB;IACtB,OAAO,CAAC,mBAAmB,CAAS;gBAExB,OAAO,EAAE,mBAAmB;IAcxC,kDAAkD;IAClD,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,EAAE,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,IAAI;IAQ/F,oFAAoF;IACpF,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,2FAA2F;IAC3F,mBAAmB,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,GAAG,IAAI;IAI5D;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAUvD,8FAA8F;IACxF,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC;;OAEG;cACa,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BzC;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI,IAAI;IAmBhC;;;;;;OAMG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,IAAI,GAAG,IAAI;IAoEtD;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAoB1B"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WinMatrix Agent SDK - DaemonClient
|
|
3
|
+
*
|
|
4
|
+
* Extends WinMatrixAgentClient for the Computer/Daemon connection model.
|
|
5
|
+
* After WebSocket connection, sends `computer.register` (instead of `register`)
|
|
6
|
+
* with the computer's identity, host info, and detected runtimes.
|
|
7
|
+
*
|
|
8
|
+
* The Daemon connection acts as a multiplexing channel:
|
|
9
|
+
* - computer.heartbeat events keep the Computer alive
|
|
10
|
+
* - agent.create / agent.stop events manage Agent lifecycle on the host
|
|
11
|
+
* - task.* messages are routed by agentId for individual agents
|
|
12
|
+
*/
|
|
13
|
+
import { METHODS, EVENTS, parseFrame, isEvent, isRequest, isResponse, } from '@winmatrix/protocol';
|
|
14
|
+
import { WinMatrixAgentClient } from './WinMatrixAgentClient.js';
|
|
15
|
+
/* ── DaemonClient ── */
|
|
16
|
+
export class DaemonClient extends WinMatrixAgentClient {
|
|
17
|
+
daemonOptions;
|
|
18
|
+
serverComputerId = null;
|
|
19
|
+
agentCreateHandler = null;
|
|
20
|
+
agentStopHandler = null;
|
|
21
|
+
profileCollector = null;
|
|
22
|
+
/** 心跳执行锁,防止定时器回调并发 */
|
|
23
|
+
heartbeatInProgress = false;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
super({
|
|
26
|
+
url: options.url,
|
|
27
|
+
apiKey: options.token,
|
|
28
|
+
agentId: `computer:${options.installationId}`,
|
|
29
|
+
name: options.hostname,
|
|
30
|
+
agentType: 'daemon',
|
|
31
|
+
capabilities: { streaming: false, toolCall: false, cancellation: false },
|
|
32
|
+
autoReconnect: options.autoReconnect,
|
|
33
|
+
bridgeHooks: options.bridgeHooks,
|
|
34
|
+
});
|
|
35
|
+
this.daemonOptions = options;
|
|
36
|
+
}
|
|
37
|
+
/** Register handler for daemon-specific events */
|
|
38
|
+
onDaemonEvent(event, handler) {
|
|
39
|
+
if (event === 'agent.create') {
|
|
40
|
+
this.agentCreateHandler = handler;
|
|
41
|
+
}
|
|
42
|
+
else if (event === 'agent.stop') {
|
|
43
|
+
this.agentStopHandler = handler;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Get the server-assigned computer ID (available after successful registration) */
|
|
47
|
+
getComputerId() {
|
|
48
|
+
return this.serverComputerId;
|
|
49
|
+
}
|
|
50
|
+
/** Set the profile collector function (called during heartbeat to attach agentProfiles) */
|
|
51
|
+
setProfileCollector(fn) {
|
|
52
|
+
this.profileCollector = fn;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 通过 daemon 连接发送 agent.error 事件。
|
|
56
|
+
* 替代直接访问私有 ws 属性,用于 agent.create 失败时通知服务端。
|
|
57
|
+
*/
|
|
58
|
+
sendAgentError(agentId, error) {
|
|
59
|
+
if (this.getState() !== 'registered')
|
|
60
|
+
return false;
|
|
61
|
+
try {
|
|
62
|
+
this.sendEvent(EVENTS.AGENT_ERROR, { agentId, error });
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Immediately send a heartbeat with agent profiles (used for agent create/destroy/rescan) */
|
|
70
|
+
async sendHeartbeatNow() {
|
|
71
|
+
if (this.getState() !== 'registered')
|
|
72
|
+
return;
|
|
73
|
+
try {
|
|
74
|
+
const agentProfiles = this.profileCollector ? await this.profileCollector() : undefined;
|
|
75
|
+
this.sendEvent(EVENTS.COMPUTER_HEARTBEAT, agentProfiles ? { agentProfiles } : undefined);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// best-effort
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/* ── Protected overrides ── */
|
|
82
|
+
/**
|
|
83
|
+
* Override register() to send computer.register instead of agent register.
|
|
84
|
+
*/
|
|
85
|
+
async register() {
|
|
86
|
+
const params = {
|
|
87
|
+
installationId: this.daemonOptions.installationId,
|
|
88
|
+
token: this.daemonOptions.token,
|
|
89
|
+
hostname: this.daemonOptions.hostname,
|
|
90
|
+
os: this.daemonOptions.hostOs,
|
|
91
|
+
arch: this.daemonOptions.hostArch,
|
|
92
|
+
daemonVersion: this.daemonOptions.daemonVersion,
|
|
93
|
+
runtimes: this.daemonOptions.runtimes,
|
|
94
|
+
};
|
|
95
|
+
if (this.daemonOptions.supportedAgentTypes?.length) {
|
|
96
|
+
params.supportedAgentTypes = this.daemonOptions.supportedAgentTypes;
|
|
97
|
+
}
|
|
98
|
+
const response = await this.sendRequest(METHODS.COMPUTER_REGISTER, params);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(`Computer registration failed: ${response.error ?? 'unknown error'}`);
|
|
101
|
+
}
|
|
102
|
+
const payload = response.payload;
|
|
103
|
+
if (payload?.computerId) {
|
|
104
|
+
this.serverComputerId = payload.computerId;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Override heartbeat for daemon mode — sends computer.heartbeat events with optional agentProfiles.
|
|
109
|
+
* 使用锁防止定时器回调并发执行,确保上次心跳完成后再调度下次。
|
|
110
|
+
*/
|
|
111
|
+
startHeartbeat() {
|
|
112
|
+
const interval = 30000;
|
|
113
|
+
this.heartbeatTimer = setInterval(async () => {
|
|
114
|
+
// 如果上次心跳还在执行,跳过本次
|
|
115
|
+
if (this.heartbeatInProgress)
|
|
116
|
+
return;
|
|
117
|
+
if (this.getState() !== 'registered')
|
|
118
|
+
return;
|
|
119
|
+
this.heartbeatInProgress = true;
|
|
120
|
+
try {
|
|
121
|
+
const agentProfiles = this.profileCollector ? await this.profileCollector() : undefined;
|
|
122
|
+
this.sendEvent(EVENTS.COMPUTER_HEARTBEAT, agentProfiles ? { agentProfiles } : undefined);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Ignore transient send failures
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
this.heartbeatInProgress = false;
|
|
129
|
+
}
|
|
130
|
+
}, interval);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Override to extract agentId before parseFrame and intercept daemon events.
|
|
134
|
+
*
|
|
135
|
+
* 注意:方案 B 下 onPassthrough 未设置,passthrough 路由代码(task.assign ACK / wrapper 响应)
|
|
136
|
+
* 当前为 dead code。每个 agent 有独立 WinMatrixAgentClient + WebSocket,消息由
|
|
137
|
+
* AgentProcessManager 分发到各 agent 的 client,不经过 daemon 连接多路复用。
|
|
138
|
+
*/
|
|
139
|
+
handleMessage(data) {
|
|
140
|
+
const raw = typeof data === 'string' ? data : data.toString('utf-8');
|
|
141
|
+
// Extract top-level agentId before parseFrame (which drops non-standard fields)
|
|
142
|
+
let agentId = null;
|
|
143
|
+
try {
|
|
144
|
+
const parsed = JSON.parse(raw);
|
|
145
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
146
|
+
if (typeof parsed.agentId === 'string' && parsed.agentId.length > 0) {
|
|
147
|
+
agentId = parsed.agentId;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Parse the frame for routing
|
|
155
|
+
const frame = parseFrame(raw);
|
|
156
|
+
if (!frame)
|
|
157
|
+
return;
|
|
158
|
+
// Intercept daemon events BEFORE parent handling
|
|
159
|
+
if (isEvent(frame)) {
|
|
160
|
+
const eventFrame = frame;
|
|
161
|
+
if (this.handleDaemonEvent(eventFrame.event, eventFrame.payload)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Pass through agent-level messages to daemon for wrapper forwarding
|
|
166
|
+
if (this.daemonOptions.onPassthrough) {
|
|
167
|
+
if (isRequest(frame)) {
|
|
168
|
+
const reqFrame = frame;
|
|
169
|
+
if (reqFrame.method === METHODS.TASK_ASSIGN) {
|
|
170
|
+
// Ack receipt, then pass through
|
|
171
|
+
this.sendRaw({ type: 'res', id: reqFrame.id, ok: true });
|
|
172
|
+
this.daemonOptions.onPassthrough(frame, raw, agentId);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
// Other unrecognized requests → pass through
|
|
176
|
+
this.daemonOptions.onPassthrough(frame, raw, agentId);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (isEvent(frame)) {
|
|
180
|
+
const evtFrame = frame;
|
|
181
|
+
// Pass through task/tool events for agent-level routing
|
|
182
|
+
if (evtFrame.event.startsWith('task.') || evtFrame.event.startsWith('tool.')) {
|
|
183
|
+
this.daemonOptions.onPassthrough(frame, raw, agentId);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Pass through response frames for forwarded wrapper requests
|
|
189
|
+
// (IDs starting with 'wrapper-'). Daemon-originated responses (IDs
|
|
190
|
+
// starting with 'sdk-') must be handled by the parent's pendingRequests.
|
|
191
|
+
if (isResponse(frame) && this.daemonOptions.onPassthrough) {
|
|
192
|
+
const resFrame = frame;
|
|
193
|
+
if (typeof resFrame.id === 'string' && resFrame.id.startsWith('wrapper-')) {
|
|
194
|
+
this.daemonOptions.onPassthrough(frame, raw, agentId);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Delegate to parent for standard message handling (responses, ping, etc.)
|
|
199
|
+
super.handleMessage(data);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Handle daemon-specific events. Returns true if the event was handled.
|
|
203
|
+
*/
|
|
204
|
+
handleDaemonEvent(event, payload) {
|
|
205
|
+
switch (event) {
|
|
206
|
+
case EVENTS.AGENT_CREATE: {
|
|
207
|
+
const createPayload = payload;
|
|
208
|
+
if (createPayload?.agentId && (createPayload?.runtime || createPayload?.agentType === 'hermes' || createPayload?.agentType === 'openclaw')) {
|
|
209
|
+
this.agentCreateHandler?.(createPayload);
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
case EVENTS.AGENT_STOP: {
|
|
214
|
+
const stopPayload = payload;
|
|
215
|
+
if (stopPayload?.agentId) {
|
|
216
|
+
this.agentStopHandler?.(stopPayload);
|
|
217
|
+
}
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
default:
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=DaemonClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DaemonClient.js","sourceRoot":"","sources":["../../src/core/DaemonClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,6 @@ export declare function daemonRuntimeEntryFromClaudeDoctor(result: ClaudeRuntime
|
|
|
8
8
|
export declare function adapterClaudePathFromRuntimeEntry(runtime: Pick<DaemonRuntimeEntry, 'available' | 'resolvedPath' | 'command'> | undefined): string | undefined;
|
|
9
9
|
export declare function runDaemonRuntimeDoctor(options?: {
|
|
10
10
|
persist?: boolean;
|
|
11
|
-
}): RuntimeDoctorSummary
|
|
11
|
+
}): Promise<RuntimeDoctorSummary>;
|
|
12
12
|
export declare function formatClaudeDoctorLines(result: ClaudeRuntimeDoctorResult): string[];
|
|
13
13
|
//# sourceMappingURL=RuntimeDoctor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuntimeDoctor.d.ts","sourceRoot":"","sources":["../../src/core/RuntimeDoctor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"RuntimeDoctor.d.ts","sourceRoot":"","sources":["../../src/core/RuntimeDoctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,yBAAyB,EAC9B,KAAK,OAAO,EACb,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,yBAAyB,CAAC;CACnC;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,yBAAyB,GAChC,kBAAkB,CAYpB;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,CAAC,GAAG,SAAS,GACtF,MAAM,GAAG,SAAS,CAKpB;AAsBD,wBAAsB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6B3G;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,EAAE,CAqBnF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { detectRuntimes, runClaudeRuntimeDoctor, } from '@winmatrix/agent-sdk';
|
|
1
|
+
import { detectRuntimes, runClaudeRuntimeDoctor, OpenClawAdapter, } from '@winmatrix/agent-sdk';
|
|
2
2
|
import { persistDaemonRuntimeToDisk, } from './ConfigLoader.js';
|
|
3
3
|
export function daemonRuntimeEntryFromClaudeDoctor(result) {
|
|
4
4
|
return {
|
|
@@ -19,7 +19,25 @@ export function adapterClaudePathFromRuntimeEntry(runtime) {
|
|
|
19
19
|
}
|
|
20
20
|
return runtime.resolvedPath ?? runtime.command;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* 探测本机 openclaw CLI 可用性(spawn `openclaw --version`)。
|
|
24
|
+
* CLI 模式下不连 gateway(无 WS-RPC scope/protocol 问题),仅验 CLI 可执行。
|
|
25
|
+
* Promise.race 3s 兜底(虽然 healthCheck 内部 spawnSync 已有 5s timeout,双保险)。
|
|
26
|
+
*/
|
|
27
|
+
async function probeOpenClawGateway(timeoutMs = 3_000) {
|
|
28
|
+
try {
|
|
29
|
+
const adapter = new OpenClawAdapter({});
|
|
30
|
+
const status = await Promise.race([
|
|
31
|
+
adapter.healthCheck(),
|
|
32
|
+
new Promise((resolve) => setTimeout(() => resolve({ available: false }), timeoutMs)),
|
|
33
|
+
]);
|
|
34
|
+
return { available: status.available, version: status.version };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { available: false };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function runDaemonRuntimeDoctor(options) {
|
|
23
41
|
const claude = runClaudeRuntimeDoctor();
|
|
24
42
|
const runtimeEntry = daemonRuntimeEntryFromClaudeDoctor(claude);
|
|
25
43
|
if (options?.persist !== false) {
|
|
@@ -32,6 +50,13 @@ export function runDaemonRuntimeDoctor(options) {
|
|
|
32
50
|
available: claude.available,
|
|
33
51
|
}
|
|
34
52
|
: runtime));
|
|
53
|
+
// openclaw 是 WS gateway(非 CLI),detectRuntimes 探不到;用 healthCheck 探测默认本机 gateway
|
|
54
|
+
const openclawStatus = await probeOpenClawGateway();
|
|
55
|
+
runtimes.push({
|
|
56
|
+
name: 'openclaw',
|
|
57
|
+
available: openclawStatus.available,
|
|
58
|
+
version: openclawStatus.version,
|
|
59
|
+
});
|
|
35
60
|
return {
|
|
36
61
|
claude,
|
|
37
62
|
runtimes,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuntimeDoctor.js","sourceRoot":"","sources":["../../src/core/RuntimeDoctor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,sBAAsB,
|
|
1
|
+
{"version":3,"file":"RuntimeDoctor.js","sourceRoot":"","sources":["../../src/core/RuntimeDoctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WinMatrix Agent SDK - Client
|
|
3
|
+
*
|
|
4
|
+
* Main client class for connecting external agents to the WinMatrix platform.
|
|
5
|
+
* Handles WebSocket connection, registration, heartbeat, task lifecycle, and tool calls.
|
|
6
|
+
*/
|
|
7
|
+
import WebSocket from 'ws';
|
|
8
|
+
import { RegisterParams, TaskAssignParams, type EngineProgressEvent, type EngineLaunchSpec, RuntimeAvailabilityPayload, BaseResponse, BaseRequest, InboundFrame } from '@winmatrix/protocol';
|
|
9
|
+
export type ClientState = 'disconnected' | 'connecting' | 'connected' | 'registered';
|
|
10
|
+
export interface TaskInput {
|
|
11
|
+
taskId: string;
|
|
12
|
+
input: string;
|
|
13
|
+
context: TaskAssignParams['context'];
|
|
14
|
+
streaming: boolean;
|
|
15
|
+
/** 服务端生成的系统提示词 */
|
|
16
|
+
systemPrompt?: string;
|
|
17
|
+
/** 本任务的 MCP ToolProxy token(per-task session ID) */
|
|
18
|
+
mcpToken?: string;
|
|
19
|
+
/** Adapter session id for resume */
|
|
20
|
+
sessionId?: string;
|
|
21
|
+
/** When true, adapter resumes sessionId */
|
|
22
|
+
resumeSession?: boolean;
|
|
23
|
+
/** 新版信封透传的工作目录(来自 LaunchSpec.workDir);V1 路径不设置。 */
|
|
24
|
+
workDir?: string;
|
|
25
|
+
/**
|
|
26
|
+
* 统一 Agent Engine Gateway Run key(`${recordId}:${attemptNo}`)。
|
|
27
|
+
* 仅在新版 task.assign 信封(launchSpec)中携带;旧版 V1 assign 时不设置。
|
|
28
|
+
* daemon 用其做幂等 launch(同一 runKey 重复 assign 不重复执行)。
|
|
29
|
+
*/
|
|
30
|
+
runKey?: string;
|
|
31
|
+
/** 新版信封的 invocation fingerprint;不同 fingerprint 拒绝为同一 runKey 启动。 */
|
|
32
|
+
invocationFingerprint?: string;
|
|
33
|
+
/** 原始 canonical LaunchSpec(结构化 input/session/model 等),供 adapter 高级用法使用。 */
|
|
34
|
+
launchSpec?: EngineLaunchSpec;
|
|
35
|
+
/** 非敏感环境变量(来自 LaunchSpec.nonSensitiveEnv)。 */
|
|
36
|
+
env?: Record<string, string>;
|
|
37
|
+
/** Claude 引擎选项(来自 LaunchSpec.permissionMode/allowedTools/engineOptions)。 */
|
|
38
|
+
claude?: {
|
|
39
|
+
permissionMode?: string;
|
|
40
|
+
tools?: string[];
|
|
41
|
+
disallowedTools?: string[];
|
|
42
|
+
systemPrompt?: string;
|
|
43
|
+
maxBudgetUsd?: number;
|
|
44
|
+
maxTurns?: number;
|
|
45
|
+
useAgentSdk?: boolean;
|
|
46
|
+
};
|
|
47
|
+
/** Hermes 引擎选项(来自 LaunchSpec.model/engineOptions)。 */
|
|
48
|
+
hermes?: {
|
|
49
|
+
model?: string;
|
|
50
|
+
provider?: string;
|
|
51
|
+
toolsets?: string[];
|
|
52
|
+
};
|
|
53
|
+
/** OpenClaw 引擎选项(来自 LaunchSpec.engineOptions)。 */
|
|
54
|
+
openclaw?: {
|
|
55
|
+
gatewayHost?: string;
|
|
56
|
+
gatewayPort?: number;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export interface WinMatrixAgentClientOptions {
|
|
60
|
+
/** WebSocket URL of the WinMatrix server (e.g. ws://localhost:8400/api/v1/external-agents/connect) */
|
|
61
|
+
url: string;
|
|
62
|
+
/** Agent identifier */
|
|
63
|
+
agentId: string;
|
|
64
|
+
/** API key for authentication */
|
|
65
|
+
apiKey: string;
|
|
66
|
+
/** Display name for this agent */
|
|
67
|
+
name: string;
|
|
68
|
+
/** Agent type identifier */
|
|
69
|
+
agentType: string;
|
|
70
|
+
/** Capability declaration */
|
|
71
|
+
capabilities: RegisterParams['capabilities'];
|
|
72
|
+
/**
|
|
73
|
+
* Optional hooks (e.g. Dual Runtime Bridge task journaling).
|
|
74
|
+
* - `onTaskAssigned`: once per task.assign, before the task handler runs.
|
|
75
|
+
* - `onTaskCompleted` / `onTaskFailed`: before task.complete / task.error frames are sent.
|
|
76
|
+
*/
|
|
77
|
+
bridgeHooks?: {
|
|
78
|
+
onTaskAssigned?: (task: TaskInput) => void;
|
|
79
|
+
/** Invoked before sending task.complete (e.g. bridge task journal). */
|
|
80
|
+
onTaskCompleted?: (taskId: string, result: unknown) => void;
|
|
81
|
+
/** Invoked before sending task.error (e.g. bridge task journal). */
|
|
82
|
+
onTaskFailed?: (taskId: string, error: string, code?: string) => void;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* When true, the client schedules its own exponential backoff reconnect on disconnect
|
|
86
|
+
* or failed connect(). Default false — prefer orchestrating reconnect at the host (daemon)
|
|
87
|
+
* so policies (auth backoff-off, single owner) stay in one place.
|
|
88
|
+
*/
|
|
89
|
+
autoReconnect?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Session query handler — called when the server sends session.list / session.get RPC.
|
|
92
|
+
* The handler receives the method name and params, and should return the result payload
|
|
93
|
+
* to send back in the response frame.
|
|
94
|
+
*/
|
|
95
|
+
sessionQueryHandler?: (method: string, params: unknown) => Promise<unknown>;
|
|
96
|
+
/** Daemon-side handler for versioned Agent Engine Run control/discovery RPCs. */
|
|
97
|
+
agentEngineRequestHandler?: (method: string, params: unknown) => Promise<unknown>;
|
|
98
|
+
/** Validate task.assign identity/capacity before acknowledging launch. */
|
|
99
|
+
taskAssignAdmission?: (params: unknown) => {
|
|
100
|
+
ok: true;
|
|
101
|
+
disposition?: 'accepted' | 'existing';
|
|
102
|
+
} | {
|
|
103
|
+
ok: false;
|
|
104
|
+
error: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
type EventHandler<T = void> = (data: T) => void | Promise<void>;
|
|
108
|
+
export declare class WinMatrixAgentClient {
|
|
109
|
+
private readonly options;
|
|
110
|
+
private ws;
|
|
111
|
+
private state;
|
|
112
|
+
protected heartbeatTimer: ReturnType<typeof setInterval> | null;
|
|
113
|
+
private reconnectTimer;
|
|
114
|
+
private reconnectDelay;
|
|
115
|
+
private readonly maxReconnectDelay;
|
|
116
|
+
private pendingRequests;
|
|
117
|
+
private requestTimeout;
|
|
118
|
+
private taskHandler;
|
|
119
|
+
private resumeHandler;
|
|
120
|
+
private disconnectHandler;
|
|
121
|
+
private errorHandler;
|
|
122
|
+
private registeredHandler;
|
|
123
|
+
private serverConfig;
|
|
124
|
+
constructor(options: WinMatrixAgentClientOptions);
|
|
125
|
+
/** Current lifecycle state */
|
|
126
|
+
getState(): ClientState;
|
|
127
|
+
/** Set or replace the session query handler after construction */
|
|
128
|
+
setSessionQueryHandler(handler: (method: string, params: unknown) => Promise<unknown>): void;
|
|
129
|
+
/** Register an event handler */
|
|
130
|
+
on(event: 'task' | 'resume' | 'disconnect' | 'error' | 'registered', handler: EventHandler<unknown>): void;
|
|
131
|
+
/** Open connection and register with the server */
|
|
132
|
+
connect(): Promise<void>;
|
|
133
|
+
/** Gracefully disconnect */
|
|
134
|
+
disconnect(): void;
|
|
135
|
+
/**
|
|
136
|
+
* 向 WinMatrix 上报本地 Hermes/OpenClaw HTTP(或命令模式)运行时可用性快照。
|
|
137
|
+
* 一般由 bridge 周期性调用;需在 `registered` 状态下发送。
|
|
138
|
+
*/
|
|
139
|
+
notifyRuntimeAvailability(payload: RuntimeAvailabilityPayload): void;
|
|
140
|
+
/** Send a streaming delta for an active task */
|
|
141
|
+
streamDelta(taskId: string, content: string, meta?: Record<string, unknown>, engineEvent?: EngineProgressEvent): void;
|
|
142
|
+
/** Mark a task as completed with a result. sessionId and usage are passed at top level for server-side DB persistence. */
|
|
143
|
+
completeTask(taskId: string, result: unknown, sessionId?: string, usage?: {
|
|
144
|
+
input: number;
|
|
145
|
+
output: number;
|
|
146
|
+
}): void;
|
|
147
|
+
/** Mark a task as failed with an error message */
|
|
148
|
+
failTask(taskId: string, error: string, code?: string): void;
|
|
149
|
+
/** Call a WinMatrix tool and wait for the result */
|
|
150
|
+
callTool(toolName: string, args: unknown, taskId?: string, agentId?: string): Promise<unknown>;
|
|
151
|
+
/**
|
|
152
|
+
* Send an arbitrary frame to the server.
|
|
153
|
+
* Wraps the low-level sendRaw, keeping the WS write path encapsulated.
|
|
154
|
+
*/
|
|
155
|
+
sendFrame(frame: Record<string, unknown>): void;
|
|
156
|
+
protected establishConnection(): Promise<void>;
|
|
157
|
+
protected register(): Promise<void>;
|
|
158
|
+
protected sendRequest(method: string, params?: unknown): Promise<BaseResponse>;
|
|
159
|
+
protected sendEvent(event: string, payload?: unknown): void;
|
|
160
|
+
protected sendRaw(data: unknown): void;
|
|
161
|
+
protected handleMessage(data: WebSocket.Data): void;
|
|
162
|
+
/**
|
|
163
|
+
* 处理服务端发来的请求帧(如 task.assign)
|
|
164
|
+
*
|
|
165
|
+
* 服务端通过 waitForResponse 发送 { type: 'req', method: 'task.assign', params } 帧,
|
|
166
|
+
* SDK 需要回复 { type: 'res', id, ok: true } 确认收到,然后异步处理任务。
|
|
167
|
+
*/
|
|
168
|
+
protected handleIncomingRequest(frame: BaseRequest): void;
|
|
169
|
+
private handleResponse;
|
|
170
|
+
protected handleEventFrame(frame: InboundFrame & {
|
|
171
|
+
type: 'event';
|
|
172
|
+
event: string;
|
|
173
|
+
payload?: unknown;
|
|
174
|
+
}): void;
|
|
175
|
+
protected setState(state: ClientState): void;
|
|
176
|
+
protected startHeartbeat(): void;
|
|
177
|
+
protected handleDisconnect(socket?: WebSocket | null): void;
|
|
178
|
+
private scheduleReconnect;
|
|
179
|
+
private cleanup;
|
|
180
|
+
private cleanupSocket;
|
|
181
|
+
}
|
|
182
|
+
export {};
|
|
183
|
+
//# sourceMappingURL=WinMatrixAgentClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WinMatrixAgentClient.d.ts","sourceRoot":"","sources":["../../src/core/WinMatrixAgentClient.ts"],"names":[],"mappings":"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"}
|