@cutie-crypto/connector-core 0.1.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/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # @cutie-crypto/connector-core
2
+
3
+ Cutie Connector core protocol + connection runtime + PlatformAdapter contract.
4
+
5
+ **Node.js only.** Uses `node:http` / `node:https` / `node:url` / `Buffer`.
6
+
7
+ ## What this package gives you
8
+
9
+ - **Protocol envelopes**: `TaskPush` / `HelloOk` / `HeartbeatAck` / `ServerMessage` / `RegisterResult` / `TaskResultMessage`
10
+ - **HTTP client**: `register(serverUrl, RegisterParams)` / `fetchStrategyKnowledge(serverUrl, token)` / `buildFormData` / `post` / `get`
11
+ - **Connection runtime**: `ConnectorConnection` class — WS loop / heartbeat / task dispatch / upgrade trigger
12
+ - **Adapter contract**: `CorePlatformAdapter<C>` — 6 methods you implement to plug a new platform
13
+
14
+ ## How to write a new adapter
15
+
16
+ ```ts
17
+ import type {
18
+ CorePlatformAdapter,
19
+ AgentResult,
20
+ SafetyTemplates,
21
+ } from '@cutie-crypto/connector-core';
22
+
23
+ interface MyConfig {
24
+ endpoint: string;
25
+ }
26
+
27
+ export class EchoAdapter implements CorePlatformAdapter<MyConfig> {
28
+ readonly id = 'echo';
29
+ private config: MyConfig | null = null;
30
+
31
+ attachConfig(config: MyConfig): void {
32
+ this.config = config;
33
+ }
34
+
35
+ async callAgent(message: string, _model: string): Promise<AgentResult> {
36
+ return { answer: `echo: ${message}`, latency_ms: 1 };
37
+ }
38
+
39
+ async selfUpgrade(_targetVersion: string): Promise<void> {
40
+ // No-op. Real adapter would: download new version, replace binary,
41
+ // process.exit(0) to let supervisor (systemd / PM2 / Zylos) restart.
42
+ }
43
+
44
+ augmentHeartbeat(envelope: Record<string, unknown>): Record<string, unknown> {
45
+ return envelope;
46
+ }
47
+
48
+ getCapabilities(): string[] {
49
+ return [];
50
+ }
51
+
52
+ applySafetyTemplates(_templates: SafetyTemplates): void {
53
+ // OpenClaw / Hermes write to workspace files.
54
+ // CLI-style adapters (Claude / Codex) cache here, splice into prompt later.
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## The 8 design constraints (Phase 0.2)
60
+
61
+ These are the contracts `connector-core` upholds so any adapter (OpenClaw,
62
+ Hermes, future Claude / Codex CLI integration) plugs in without touching core:
63
+
64
+ 1. **AI call abstraction**: `adapter.callAgent(message, model) → {answer, latency_ms}`. Core does not assume HTTP / CLI.
65
+ 2. **Config layering**: top-level holds shared fields; platform-specific config is the generic `C` parameter on `CorePlatformAdapter<C>`. Each adapter sees only its own config type.
66
+ 3. **Safety template dispatch**: `adapter.applySafetyTemplates({agents_md, soul_md, canary_token?})` — core delivers what server's `register` returns; adapter decides how to land it (file vs cache). Called only after pairing/setup succeeds.
67
+ 4. **Self-upgrade**: `adapter.selfUpgrade(targetVersion)` — adapter chooses install method. Core does not hardcode `npm install`.
68
+ 5. **Process management**: core does not assume systemd / PM2 / launchd. Adapter's `selfUpgrade` typically `process.exit(0)` to let supervisor restart.
69
+ 6. **Unified `agent_status`**: core builds heartbeat with `agent_status`; adapter's `augmentHeartbeat` adds backward-compat fields (e.g. `openclaw_status` mirroring `agent_status`).
70
+ 7. **README + dummy adapter**: see the compilable `EchoAdapter` example above in *How to write a new adapter*.
71
+ 8. **Capability flags**: `register` form / `heartbeat` envelope carry optional `capabilities: string[]`. Adapter returns `[]` today; future adapters declare e.g. `['sandbox=srt', 'runtime=claude']`.
72
+
73
+ ## When to call `applySafetyTemplates`
74
+
75
+ Only after `register` HTTP response returns templates. **Never** during install /
76
+ post-install hooks — there's no `pair_token` yet, so the templates haven't been
77
+ generated by Cutie Server.
78
+
79
+ ## Runtime requirements
80
+
81
+ Node.js >= 18.
@@ -0,0 +1,80 @@
1
+ /**
2
+ * CorePlatformAdapter — core 知道的 6 件 adapter 必须做的事。
3
+ *
4
+ * connector / zylos-cutie / 任何未来 adapter 都实现这个接口。core 不假设
5
+ * 平台命名、不假设进程管理(systemd / PM2)、不假设网络协议(HTTP / CLI)。
6
+ *
7
+ * Generic `C` = adapter 自己的 platform-specific config 类型。OpenClaw /
8
+ * Hermes / 未来 zylos-cutie 各自实例化自己的 C,编译期隔离 adapter 之间的
9
+ * 字段访问(约束 2)。
10
+ */
11
+ export interface AgentResult {
12
+ answer: string;
13
+ latency_ms: number;
14
+ }
15
+ /**
16
+ * 安全模板:server `register` response 下发的 agents_md / soul_md,由 adapter
17
+ * 决定如何落地(OpenClaw/Hermes 写 workspace;zylos-cutie 缓存供 prompt-builder
18
+ * 拼接)。canary_token 当前 server 不下发,作为 future-proof 占位。
19
+ */
20
+ export interface SafetyTemplates {
21
+ agents_md: string;
22
+ soul_md: string;
23
+ /** future: server 下发的 KOL 实例级 canary token;当前 undefined */
24
+ canary_token?: string;
25
+ }
26
+ export interface CorePlatformAdapter<C = unknown> {
27
+ /** 平台 ID,仅供日志/调试。core 不约束值('openclaw' / 'hermes' / 未来 'zylos')。 */
28
+ readonly id: string;
29
+ /**
30
+ * 注入平台特定 config 子集(约束 2)。
31
+ *
32
+ * Generic `C` 让每个 adapter 在编译期只看到自己关心的字段:OpenClaw 拿
33
+ * OpenClawAdapterConfig,Hermes 拿 HermesAdapterConfig,互相不串。core 不知道
34
+ * adapter 各自的 config schema,仅作为 contract 占位。
35
+ *
36
+ * connector 包的 ConnectorConnection wrapper 在创建 core ConnectorConnection
37
+ * 之前先调本方法,把 ConnectorConfig 中跟当前平台相关的窄字段挑出来注入。
38
+ */
39
+ attachConfig(config: C): void;
40
+ /**
41
+ * 调用本地 AI agent。OpenClaw/Hermes 走 HTTP gateway;zylos-cutie 未来
42
+ * spawn `claude -p` / `codex exec`。core 不假设实现方式。
43
+ */
44
+ callAgent(message: string, model: string): Promise<AgentResult>;
45
+ /**
46
+ * 触发自升级。targetVersion 由 server heartbeat_ack 下发。
47
+ * core 不假设进程管理:adapter 内部完成 install + 通常 process.exit(0) 让
48
+ * 外层守护(systemd / PM2 / Zylos hooks)自动重启。core 不要求 selfUpgrade
49
+ * 一定 return(实际跑成功的话 adapter 已经 exit)。
50
+ */
51
+ selfUpgrade(targetVersion: string): Promise<void>;
52
+ /**
53
+ * core 构造完 heartbeat envelope(含 agent_status 等通用字段)后调,让
54
+ * adapter 注入平台特定字段。
55
+ *
56
+ * 例:
57
+ * - OpenClaw 加 openclaw_status(兼容旧 server 字段,mirror agent_status)
58
+ * - Hermes 加 openclaw_status + hermes_isolation_level + auto_start_configured
59
+ * - 未来 zylos-cutie 不加任何字段
60
+ *
61
+ * 必须返回 envelope(可以是同一对象 mutate,也可以是新对象)。
62
+ */
63
+ augmentHeartbeat(envelope: Record<string, unknown>): Record<string, unknown>;
64
+ /**
65
+ * 上报 adapter 能力(约束 8)。OpenClaw/Hermes 当前返回 `[]`;
66
+ * zylos-cutie 未来上报 `['sandbox=srt', 'runtime=claude']` 等。Server 暂不读,
67
+ * 字段是 future-proof 占位。
68
+ */
69
+ getCapabilities(): string[];
70
+ /**
71
+ * 把 server register response 下发的安全模板交给 adapter 落地(约束 3)。
72
+ * - OpenClaw / Hermes: 写到 workspace 文件(agent CLI 启动时读入)
73
+ * - 未来 zylos-cutie: 缓存到内存供 prompt-builder 拼接(Claude/Codex CLI
74
+ * 没有 workspace 自动加载机制)
75
+ *
76
+ * ⚠️ 必须在 pairing/setup 成功(即 register response 返回模板)后才调用,
77
+ * 不能在安装期 / 没有 pair_token 时调用。
78
+ */
79
+ applySafetyTemplates(templates: SafetyTemplates): void;
80
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * CorePlatformAdapter — core 知道的 6 件 adapter 必须做的事。
4
+ *
5
+ * connector / zylos-cutie / 任何未来 adapter 都实现这个接口。core 不假设
6
+ * 平台命名、不假设进程管理(systemd / PM2)、不假设网络协议(HTTP / CLI)。
7
+ *
8
+ * Generic `C` = adapter 自己的 platform-specific config 类型。OpenClaw /
9
+ * Hermes / 未来 zylos-cutie 各自实例化自己的 C,编译期隔离 adapter 之间的
10
+ * 字段访问(约束 2)。
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * ConnectorConnection — connector 协议主循环(WS 连接 / 心跳 / 任务派发 /
3
+ * 自升级触发)。core 不假设:
4
+ * - 进程管理(systemd / PM2 / launchd / Zylos hooks)
5
+ * - 配置文件路径 / schema(adapter 包提供 CoreConnectionConfig 即可)
6
+ * - 平台命名(agent_platform 是任意 string)
7
+ * - logger 实现(通过 deps.logger 注入;缺省 no-op)
8
+ * - HTTP 调用方式(adapter.callAgent 决定)
9
+ * - 升级方式(adapter.selfUpgrade 决定)
10
+ */
11
+ import type { CorePlatformAdapter } from './adapter';
12
+ export interface CoreConnectionConfig {
13
+ connector_id: string;
14
+ connector_token: string;
15
+ server_url: string;
16
+ ws_url: string;
17
+ /** 'openclaw' / 'hermes' / 未来 'zylos' — core 仅作为 envelope 的 agent_platform 字段透传 */
18
+ agent_platform: string;
19
+ /** 服务端可在 hello_ok 中下调,保存当前生效值用于 setInterval 周期 */
20
+ heartbeat_interval_seconds: number;
21
+ }
22
+ export interface ConnectorConnectionLogger {
23
+ info: (msg: string, ...args: unknown[]) => void;
24
+ warn: (msg: string, ...args: unknown[]) => void;
25
+ error: (msg: string, ...args: unknown[]) => void;
26
+ }
27
+ export interface ConnectorConnectionDeps {
28
+ config: CoreConnectionConfig;
29
+ adapter: CorePlatformAdapter;
30
+ /** adapter 自己的版本号(packages/connector 的 package.json version) */
31
+ connectorVersion: string;
32
+ /** 日志钩子,core 不假设 logger 实现 */
33
+ logger?: ConnectorConnectionLogger;
34
+ }
35
+ export declare class ConnectorConnection {
36
+ private config;
37
+ private adapter;
38
+ private connectorVersion;
39
+ private log;
40
+ private ws;
41
+ private heartbeatTimer;
42
+ private reconnectTimer;
43
+ private reconnectDelay;
44
+ private maxReconnectDelay;
45
+ private running;
46
+ private authFailCount;
47
+ private readonly maxAuthFails;
48
+ private lastError;
49
+ private upgrading;
50
+ private upgradeFailedAt;
51
+ constructor(deps: ConnectorConnectionDeps);
52
+ start(): void;
53
+ stop(): void;
54
+ private cleanup;
55
+ private connect;
56
+ private scheduleReconnect;
57
+ private handleMessage;
58
+ private handleTask;
59
+ private startHeartbeat;
60
+ private doHeartbeat;
61
+ private triggerSelfUpgrade;
62
+ private send;
63
+ }
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ /**
3
+ * ConnectorConnection — connector 协议主循环(WS 连接 / 心跳 / 任务派发 /
4
+ * 自升级触发)。core 不假设:
5
+ * - 进程管理(systemd / PM2 / launchd / Zylos hooks)
6
+ * - 配置文件路径 / schema(adapter 包提供 CoreConnectionConfig 即可)
7
+ * - 平台命名(agent_platform 是任意 string)
8
+ * - logger 实现(通过 deps.logger 注入;缺省 no-op)
9
+ * - HTTP 调用方式(adapter.callAgent 决定)
10
+ * - 升级方式(adapter.selfUpgrade 决定)
11
+ */
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.ConnectorConnection = void 0;
17
+ const ws_1 = __importDefault(require("ws"));
18
+ const protocol_1 = require("./protocol");
19
+ const NOOP_LOGGER = {
20
+ info: () => undefined,
21
+ warn: () => undefined,
22
+ error: () => undefined,
23
+ };
24
+ class ConnectorConnection {
25
+ config;
26
+ adapter;
27
+ connectorVersion;
28
+ log;
29
+ ws = null;
30
+ heartbeatTimer = null;
31
+ reconnectTimer = null;
32
+ reconnectDelay = 3000;
33
+ maxReconnectDelay = 60000;
34
+ running = false;
35
+ authFailCount = 0;
36
+ maxAuthFails = 5;
37
+ lastError;
38
+ upgrading = false;
39
+ upgradeFailedAt = 0;
40
+ constructor(deps) {
41
+ this.config = deps.config;
42
+ this.adapter = deps.adapter;
43
+ this.connectorVersion = deps.connectorVersion;
44
+ this.log = deps.logger ?? NOOP_LOGGER;
45
+ }
46
+ start() {
47
+ this.running = true;
48
+ this.connect();
49
+ }
50
+ stop() {
51
+ this.running = false;
52
+ this.cleanup();
53
+ this.log.info('Connector stopped');
54
+ }
55
+ cleanup() {
56
+ if (this.heartbeatTimer) {
57
+ clearInterval(this.heartbeatTimer);
58
+ this.heartbeatTimer = null;
59
+ }
60
+ if (this.reconnectTimer) {
61
+ clearTimeout(this.reconnectTimer);
62
+ this.reconnectTimer = null;
63
+ }
64
+ if (this.ws) {
65
+ this.ws.removeAllListeners();
66
+ if (this.ws.readyState === ws_1.default.OPEN || this.ws.readyState === ws_1.default.CONNECTING) {
67
+ this.ws.close();
68
+ }
69
+ this.ws = null;
70
+ }
71
+ }
72
+ connect() {
73
+ if (!this.running)
74
+ return;
75
+ this.cleanup();
76
+ let wsEndpoint;
77
+ const rawWsUrl = this.config.ws_url || '';
78
+ if (rawWsUrl.startsWith('wss://') || rawWsUrl.startsWith('ws://')) {
79
+ wsEndpoint = rawWsUrl;
80
+ }
81
+ else if (rawWsUrl.startsWith('/')) {
82
+ wsEndpoint = this.config.server_url.replace(/^http/, 'ws') + rawWsUrl;
83
+ }
84
+ else {
85
+ wsEndpoint = this.config.server_url.replace(/^http/, 'ws') + '/v1/connector/ws';
86
+ }
87
+ const wsUrl = `${wsEndpoint}?connector_id=${encodeURIComponent(this.config.connector_id)}`;
88
+ this.log.info(`Connecting to ${wsEndpoint}...`);
89
+ this.ws = new ws_1.default(wsUrl, {
90
+ headers: {
91
+ 'Authorization': `Bearer ${this.config.connector_token}`,
92
+ },
93
+ handshakeTimeout: 10000,
94
+ });
95
+ this.ws.on('open', () => {
96
+ this.log.info('WebSocket connected');
97
+ this.reconnectDelay = 3000;
98
+ this.authFailCount = 0;
99
+ // Send hello, heartbeat starts after hello_ok
100
+ this.send({
101
+ type: 'hello',
102
+ connector_id: this.config.connector_id,
103
+ protocol_version: protocol_1.PROTOCOL_VERSION,
104
+ connector_version: this.connectorVersion,
105
+ });
106
+ });
107
+ this.ws.on('message', (raw) => {
108
+ try {
109
+ const msg = JSON.parse(raw.toString());
110
+ this.handleMessage(msg);
111
+ }
112
+ catch {
113
+ this.log.error('Failed to parse message:', raw.toString().slice(0, 200));
114
+ }
115
+ });
116
+ this.ws.on('close', (code, reason) => {
117
+ this.log.warn(`WebSocket closed: ${code} ${reason.toString()}`);
118
+ this.scheduleReconnect();
119
+ });
120
+ this.ws.on('error', (err) => {
121
+ this.log.error('WebSocket error:', err.message);
122
+ if (err.message.includes('403') || err.message.includes('401')) {
123
+ this.authFailCount++;
124
+ if (this.authFailCount >= this.maxAuthFails) {
125
+ this.log.error(`Authentication failed ${this.maxAuthFails} times consecutively. Token is likely invalid.`);
126
+ this.log.error('Run "cutie-connector reset" then re-pair with a new token.');
127
+ this.stop();
128
+ }
129
+ }
130
+ });
131
+ }
132
+ scheduleReconnect() {
133
+ if (!this.running)
134
+ return;
135
+ this.cleanup();
136
+ this.log.info(`Reconnecting in ${this.reconnectDelay / 1000}s...`);
137
+ this.reconnectTimer = setTimeout(() => {
138
+ this.connect();
139
+ }, this.reconnectDelay);
140
+ this.reconnectDelay = Math.min(this.reconnectDelay * 1.5, this.maxReconnectDelay);
141
+ }
142
+ handleMessage(msg) {
143
+ switch (msg.type) {
144
+ case 'hello_ok':
145
+ this.log.info(`Server hello_ok: max_concurrency=${msg.max_concurrency}, heartbeat=${msg.heartbeat_interval_seconds}s`);
146
+ if (msg.heartbeat_interval_seconds > 0) {
147
+ this.config.heartbeat_interval_seconds = msg.heartbeat_interval_seconds;
148
+ }
149
+ this.startHeartbeat();
150
+ break;
151
+ case 'task.push':
152
+ this.handleTask(msg);
153
+ break;
154
+ case 'heartbeat_ack':
155
+ if (msg.upgrade_required) {
156
+ this.log.info(`Upgrade available: ${this.connectorVersion} → ${msg.target_version}`);
157
+ this.triggerSelfUpgrade(msg.target_version);
158
+ }
159
+ break;
160
+ default:
161
+ this.log.warn('Unknown message type:', msg.type);
162
+ }
163
+ }
164
+ async handleTask(task) {
165
+ this.log.info(`Task received: ${task.task_id} (${task.task_type}/${task.payload.scene})`);
166
+ // Send ack
167
+ this.send({ type: 'task.ack', task_id: task.task_id });
168
+ const start = Date.now();
169
+ try {
170
+ // adapter.callAgent 内部决定 model 映射 / HTTP / spawn 等实现细节
171
+ const result = await this.adapter.callAgent(task.payload.message, task.payload.agent_model);
172
+ this.send({
173
+ type: 'task.result',
174
+ task_id: task.task_id,
175
+ status: 'success',
176
+ answer: result.answer,
177
+ latency_ms: result.latency_ms,
178
+ error_type: null,
179
+ error_message: null,
180
+ });
181
+ this.lastError = undefined;
182
+ this.log.info(`Task ${task.task_id} completed in ${result.latency_ms}ms`);
183
+ }
184
+ catch (err) {
185
+ const latency_ms = Date.now() - start;
186
+ const message = err instanceof Error ? err.message : String(err);
187
+ this.send({
188
+ type: 'task.result',
189
+ task_id: task.task_id,
190
+ status: 'error',
191
+ answer: '',
192
+ latency_ms,
193
+ // error_type 字段名保持 'openclaw_error':server 端契约名(task 严格禁区,
194
+ // 不在 PR #3a 里改)。新 platform adapter 后续若要细分错误类型,由 adapter
195
+ // 在抛出 Error 时把分类写进 message,core 这里仍统一标 'openclaw_error'。
196
+ error_type: 'openclaw_error',
197
+ error_message: message,
198
+ });
199
+ this.lastError = { type: 'openclaw_error', message };
200
+ this.log.error(`Task ${task.task_id} failed:`, message);
201
+ }
202
+ }
203
+ startHeartbeat() {
204
+ if (this.heartbeatTimer)
205
+ clearInterval(this.heartbeatTimer);
206
+ const interval = (this.config.heartbeat_interval_seconds || 30) * 1000;
207
+ // Immediate first heartbeat
208
+ this.doHeartbeat();
209
+ this.heartbeatTimer = setInterval(() => {
210
+ this.doHeartbeat();
211
+ }, interval);
212
+ }
213
+ doHeartbeat() {
214
+ const agentStatus = this.lastError ? 'error' : 'online';
215
+ // core 构造通用 envelope(不含平台特定字段)
216
+ const envelope = {
217
+ type: 'heartbeat',
218
+ connector_id: this.config.connector_id,
219
+ connector_version: this.connectorVersion,
220
+ protocol_version: protocol_1.PROTOCOL_VERSION,
221
+ connector_status: 'online',
222
+ agent_platform: this.config.agent_platform,
223
+ agent_status: agentStatus,
224
+ agent_version: '',
225
+ last_error_type: this.lastError?.type ?? null,
226
+ last_error_message: this.lastError?.message ?? null,
227
+ capabilities: this.adapter.getCapabilities(),
228
+ };
229
+ // adapter 加平台特定字段(OpenClaw/Hermes: openclaw_status mirror /
230
+ // hermes_isolation_level / auto_start_configured;zylos-cutie 不加)
231
+ const finalEnvelope = this.adapter.augmentHeartbeat(envelope);
232
+ this.send(finalEnvelope);
233
+ }
234
+ triggerSelfUpgrade(targetVersion) {
235
+ if (this.upgrading)
236
+ return;
237
+ // 升级失败后冷却 10 分钟再重试
238
+ if (this.upgradeFailedAt && Date.now() - this.upgradeFailedAt < 600000)
239
+ return;
240
+ if (!/^\d+\.\d+\.\d+$/.test(targetVersion)) {
241
+ this.log.error(`Invalid target version format: ${targetVersion}`);
242
+ return;
243
+ }
244
+ this.upgrading = true;
245
+ this.log.info(`Auto-upgrading to v${targetVersion}...`);
246
+ // adapter 决定怎么升级 + 是否 process.exit。core 不假设 systemd / PM2。
247
+ // 成功路径下 adapter 通常 process.exit(0),所以这个 promise 不一定 resolve;
248
+ // 失败路径下 adapter reject,core 重置 upgrading flag + 记录失败时间冷却 10min。
249
+ this.adapter.selfUpgrade(targetVersion).catch((err) => {
250
+ const message = err instanceof Error ? err.message : String(err);
251
+ this.log.error(`Auto-upgrade failed: ${message}`);
252
+ this.upgrading = false;
253
+ this.upgradeFailedAt = Date.now();
254
+ });
255
+ }
256
+ send(data) {
257
+ if (this.ws?.readyState === ws_1.default.OPEN) {
258
+ this.ws.send(JSON.stringify(data));
259
+ }
260
+ }
261
+ }
262
+ exports.ConnectorConnection = ConnectorConnection;
263
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Cutie Connector HTTP 客户端
3
+ *
4
+ * 通用 HTTP 调用 + 业务级 register / fetchStrategyKnowledge。
5
+ * core 不假设 platform 命名(OpenClaw / Hermes / Zylos),不依赖 os 模块(device_name
6
+ * 由 adapter 调用方传入)。
7
+ */
8
+ import type { RegisterResult } from './protocol';
9
+ export interface ApiResponse<T = unknown> {
10
+ err_code: number;
11
+ err_msg: string;
12
+ data: T;
13
+ }
14
+ export interface StrategyKnowledgeResult {
15
+ strategy_md: string | null;
16
+ updated: boolean;
17
+ }
18
+ export declare function buildFormData(params: Record<string, string | number>): string;
19
+ export declare function post<T>(baseUrl: string, path: string, params: Record<string, string | number>): Promise<ApiResponse<T>>;
20
+ export declare function get<T>(baseUrl: string, path: string, token: string): Promise<ApiResponse<T>>;
21
+ export interface RegisterParams {
22
+ pairToken: string;
23
+ /** os.platform() 结果 — core 不假设具体值 */
24
+ platform: string;
25
+ /** os.hostname() 结果 */
26
+ deviceName: string;
27
+ /** adapter 自己的版本号(@cutie-crypto/connector 的 package.json version) */
28
+ connectorVersion: string;
29
+ /** 'openclaw' / 'hermes' / future 'zylos' — core 不约束 union */
30
+ agentPlatform: string;
31
+ agentVersion: string;
32
+ /**
33
+ * 约束 8:adapter 上报的能力。OpenClaw/Hermes 当前 [];zylos-cutie 未来可能上报
34
+ * `['sandbox=srt', 'runtime=claude']`。Server 暂不读,字段是 future-proof 占位。
35
+ * 缺省(undefined)时 form 不带 capabilities 字段,保持完全旧 wire 兼容。
36
+ */
37
+ capabilities?: string[];
38
+ }
39
+ export declare function register(serverUrl: string, params: RegisterParams): Promise<RegisterResult>;
40
+ export declare function fetchStrategyKnowledge(serverUrl: string, connectorToken: string): Promise<StrategyKnowledgeResult>;
package/dist/http.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * Cutie Connector HTTP 客户端
4
+ *
5
+ * 通用 HTTP 调用 + 业务级 register / fetchStrategyKnowledge。
6
+ * core 不假设 platform 命名(OpenClaw / Hermes / Zylos),不依赖 os 模块(device_name
7
+ * 由 adapter 调用方传入)。
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.buildFormData = buildFormData;
14
+ exports.post = post;
15
+ exports.get = get;
16
+ exports.register = register;
17
+ exports.fetchStrategyKnowledge = fetchStrategyKnowledge;
18
+ const https_1 = __importDefault(require("https"));
19
+ const http_1 = __importDefault(require("http"));
20
+ const url_1 = require("url");
21
+ const protocol_1 = require("./protocol");
22
+ function buildFormData(params) {
23
+ return Object.entries(params)
24
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
25
+ .join('&');
26
+ }
27
+ function post(baseUrl, path, params) {
28
+ return new Promise((resolve, reject) => {
29
+ const url = new url_1.URL(path, baseUrl);
30
+ const body = buildFormData(params);
31
+ const mod = url.protocol === 'https:' ? https_1.default : http_1.default;
32
+ const req = mod.request(url, {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/x-www-form-urlencoded',
36
+ 'Content-Length': Buffer.byteLength(body),
37
+ },
38
+ timeout: 15000,
39
+ }, (res) => {
40
+ let data = '';
41
+ res.on('data', (chunk) => { data += chunk; });
42
+ res.on('end', () => {
43
+ try {
44
+ resolve(JSON.parse(data));
45
+ }
46
+ catch {
47
+ reject(new Error(`Invalid JSON response: ${data.slice(0, 200)}`));
48
+ }
49
+ });
50
+ });
51
+ req.on('error', reject);
52
+ req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
53
+ req.write(body);
54
+ req.end();
55
+ });
56
+ }
57
+ function get(baseUrl, path, token) {
58
+ return new Promise((resolve, reject) => {
59
+ const url = new url_1.URL(path, baseUrl);
60
+ const mod = url.protocol === 'https:' ? https_1.default : http_1.default;
61
+ const req = mod.request(url, {
62
+ method: 'GET',
63
+ headers: { 'Authorization': `Bearer ${token}` },
64
+ timeout: 15000,
65
+ }, (res) => {
66
+ let data = '';
67
+ res.on('data', (chunk) => { data += chunk; });
68
+ res.on('end', () => {
69
+ try {
70
+ resolve(JSON.parse(data));
71
+ }
72
+ catch {
73
+ reject(new Error(`Invalid JSON response: ${data.slice(0, 200)}`));
74
+ }
75
+ });
76
+ });
77
+ req.on('error', reject);
78
+ req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
79
+ req.end();
80
+ });
81
+ }
82
+ async function register(serverUrl, params) {
83
+ const formParams = {
84
+ pair_token: params.pairToken,
85
+ platform: params.platform,
86
+ device_name: params.deviceName,
87
+ connector_version: params.connectorVersion,
88
+ protocol_version: protocol_1.PROTOCOL_VERSION,
89
+ agent_platform: params.agentPlatform,
90
+ agent_version: params.agentVersion,
91
+ };
92
+ // form-urlencoded 不天然支持数组,用 JSON 字符串单字段编码(server 读到 string 后 JSON.parse)。
93
+ // 仅在调用方显式传 capabilities 时才加字段;undefined 时不带,跟旧 wire 字节级一致。
94
+ if (params.capabilities !== undefined) {
95
+ formParams.capabilities = JSON.stringify(params.capabilities);
96
+ }
97
+ const res = await post(serverUrl, '/v1/connector/register', formParams);
98
+ if (res.err_code !== 100) {
99
+ throw new Error(`Register failed (${res.err_code}): ${res.err_msg}`);
100
+ }
101
+ return res.data;
102
+ }
103
+ async function fetchStrategyKnowledge(serverUrl, connectorToken) {
104
+ const res = await get(serverUrl, '/v1/connector/strategy-knowledge', connectorToken);
105
+ if (res.err_code !== 100) {
106
+ throw new Error(`Fetch strategy knowledge failed (${res.err_code}): ${res.err_msg}`);
107
+ }
108
+ return res.data;
109
+ }
110
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @cutie-crypto/connector-core — Node.js only.
3
+ *
4
+ * `./protocol` 是纯类型 / 常量,本身可在任何 JS 运行时跑;
5
+ * `./http` 用了 node:https / node:http / node:url + Buffer,**不能在 browser / RN 跑**。
6
+ *
7
+ * 本 barrel 同时导出两者。如果未来出现非 Node 消费者(极少见 — 当前所有 adapter
8
+ * 都是 Node-side:cutie-connector 走 systemd / zylos-cutie 走 PM2),考虑改用
9
+ * subpath export("./protocol" / "./http")拆开。
10
+ */
11
+ export * from './protocol';
12
+ export * from './http';
13
+ export * from './adapter';
14
+ export * from './connection';
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * @cutie-crypto/connector-core — Node.js only.
19
+ *
20
+ * `./protocol` 是纯类型 / 常量,本身可在任何 JS 运行时跑;
21
+ * `./http` 用了 node:https / node:http / node:url + Buffer,**不能在 browser / RN 跑**。
22
+ *
23
+ * 本 barrel 同时导出两者。如果未来出现非 Node 消费者(极少见 — 当前所有 adapter
24
+ * 都是 Node-side:cutie-connector 走 systemd / zylos-cutie 走 PM2),考虑改用
25
+ * subpath export("./protocol" / "./http")拆开。
26
+ */
27
+ __exportStar(require("./protocol"), exports);
28
+ __exportStar(require("./http"), exports);
29
+ __exportStar(require("./adapter"), exports);
30
+ __exportStar(require("./connection"), exports);
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,6CAA2B;AAC3B,yCAAuB;AACvB,4CAA0B;AAC1B,+CAA6B"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Cutie Connector 协议定义
3
+ *
4
+ * 这里只放协议 types 和版本常量,不放任何运行环境相关代码(HTTP/WS/CLI/fs)。
5
+ * Server <-> Connector envelope 字段必须与现网保持完全一致,新增字段必须可选。
6
+ */
7
+ /** WebSocket 协议版本,server hello / register / heartbeat envelope 都带这个字段 */
8
+ export declare const PROTOCOL_VERSION = 1;
9
+ /**
10
+ * connector-core 包自身版本(独立于具体 adapter 的版本号)。
11
+ *
12
+ * 注意:发送给 server 的 envelope 字段 `connector_version` 报的是 *adapter* 包版本
13
+ * (例如 @cutie-crypto/connector 的 2.0.x),不是 core 版本。adapter 自己读自己的
14
+ * package.json 来填这个字段,core 不参与。
15
+ *
16
+ * CORE_VERSION 仅供后续 adapter 在 capability 上报时引用,PR #1 暂不进入任何 envelope。
17
+ *
18
+ * ⚠️ 发版纪律:CORE_VERSION 与 packages/connector-core/package.json 的 version 字段
19
+ * 必须同步更新。
20
+ *
21
+ * 实施说明(PR #4 决策):原计划 `import pkg from '../package.json'`,但需要把
22
+ * tsconfig rootDir 拉到 package 根(或 include 加 package.json),结果 dist 产物
23
+ * 变成 `dist/src/index.js`,污染 published tarball 路径。权衡后选择"hardcode +
24
+ * 注释 + 单测兜底":connector-core/src/protocol.test.ts 强校验
25
+ * `CORE_VERSION === pkg.version`,bump 时漏改即被单测拦截。BACKLOG(PR #4 后续):
26
+ * 等到 connector-core 真正公开发布时再考虑 dist 路径调整 / 改 build 脚本注入。
27
+ */
28
+ export declare const CORE_VERSION = "0.1.0";
29
+ export interface TaskPayload {
30
+ kol_user_id: string;
31
+ caller_user_id: string;
32
+ scene: string;
33
+ agent_model: string;
34
+ message: string;
35
+ }
36
+ export interface TaskPush {
37
+ type: 'task.push';
38
+ task_id: string;
39
+ task_type: string;
40
+ timeout_seconds: number;
41
+ payload: TaskPayload;
42
+ }
43
+ export interface HelloOk {
44
+ type: 'hello_ok';
45
+ max_concurrency: number;
46
+ heartbeat_interval_seconds: number;
47
+ }
48
+ export interface HeartbeatAck {
49
+ type: 'heartbeat_ack';
50
+ target_version: string;
51
+ upgrade_required: boolean;
52
+ }
53
+ export type ServerMessage = TaskPush | HelloOk | HeartbeatAck;
54
+ export interface RegisterResult {
55
+ connector_id: string;
56
+ connector_token: string;
57
+ ws_url: string;
58
+ heartbeat_interval_seconds: number;
59
+ min_supported_version: string;
60
+ target_version: string;
61
+ agents_md?: string;
62
+ soul_md?: string;
63
+ }
64
+ export interface TaskResultMessage {
65
+ type: 'task.result';
66
+ task_id: string;
67
+ status: 'success' | 'error';
68
+ answer: string;
69
+ latency_ms: number;
70
+ /** 失败时填错误码,成功时为 null */
71
+ error_type: string | null;
72
+ /** 失败时填错误描述,成功时为 null */
73
+ error_message: string | null;
74
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Cutie Connector 协议定义
4
+ *
5
+ * 这里只放协议 types 和版本常量,不放任何运行环境相关代码(HTTP/WS/CLI/fs)。
6
+ * Server <-> Connector envelope 字段必须与现网保持完全一致,新增字段必须可选。
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CORE_VERSION = exports.PROTOCOL_VERSION = void 0;
10
+ /** WebSocket 协议版本,server hello / register / heartbeat envelope 都带这个字段 */
11
+ exports.PROTOCOL_VERSION = 1;
12
+ /**
13
+ * connector-core 包自身版本(独立于具体 adapter 的版本号)。
14
+ *
15
+ * 注意:发送给 server 的 envelope 字段 `connector_version` 报的是 *adapter* 包版本
16
+ * (例如 @cutie-crypto/connector 的 2.0.x),不是 core 版本。adapter 自己读自己的
17
+ * package.json 来填这个字段,core 不参与。
18
+ *
19
+ * CORE_VERSION 仅供后续 adapter 在 capability 上报时引用,PR #1 暂不进入任何 envelope。
20
+ *
21
+ * ⚠️ 发版纪律:CORE_VERSION 与 packages/connector-core/package.json 的 version 字段
22
+ * 必须同步更新。
23
+ *
24
+ * 实施说明(PR #4 决策):原计划 `import pkg from '../package.json'`,但需要把
25
+ * tsconfig rootDir 拉到 package 根(或 include 加 package.json),结果 dist 产物
26
+ * 变成 `dist/src/index.js`,污染 published tarball 路径。权衡后选择"hardcode +
27
+ * 注释 + 单测兜底":connector-core/src/protocol.test.ts 强校验
28
+ * `CORE_VERSION === pkg.version`,bump 时漏改即被单测拦截。BACKLOG(PR #4 后续):
29
+ * 等到 connector-core 真正公开发布时再考虑 dist 路径调整 / 改 build 脚本注入。
30
+ */
31
+ exports.CORE_VERSION = '0.1.0';
32
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,yEAAyE;AAC5D,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,YAAY,GAAG,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@cutie-crypto/connector-core",
3
+ "version": "0.1.0",
4
+ "description": "Cutie Connector core protocol types and shared abstractions (Node.js only — HTTP transport uses node:https/http)",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "lint": "tsc --noEmit",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest",
13
+ "test:coverage": "vitest run --coverage"
14
+ },
15
+ "keywords": ["cutie", "connector", "protocol", "ai", "kol"],
16
+ "author": "Cutie Team",
17
+ "license": "MIT",
18
+ "files": ["dist", "README.md"],
19
+ "engines": { "node": ">=18" },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.14.0",
25
+ "@vitest/coverage-v8": "^2.1.0",
26
+ "typescript": "^5.5.0",
27
+ "vitest": "^2.1.0"
28
+ }
29
+ }