openclaw-nim 0.0.1

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/src/targets.ts ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Normalize a NIM target to a plain account ID.
3
+ * Strips common prefixes like "nim:", "user:", etc.
4
+ */
5
+ export function normalizeNimTarget(target: string): string | null {
6
+ if (!target || typeof target !== "string") {
7
+ return null;
8
+ }
9
+
10
+ let normalized = target.trim();
11
+
12
+ // Remove common prefixes
13
+ const prefixes = ["nim:", "user:", "account:", "p2p:"];
14
+ for (const prefix of prefixes) {
15
+ if (normalized.toLowerCase().startsWith(prefix)) {
16
+ normalized = normalized.slice(prefix.length);
17
+ break;
18
+ }
19
+ }
20
+
21
+ normalized = normalized.trim();
22
+
23
+ if (!normalized) {
24
+ return null;
25
+ }
26
+
27
+ return normalized;
28
+ }
29
+
30
+ /**
31
+ * Check if a string looks like a NIM account ID.
32
+ * NIM account IDs are alphanumeric strings, typically 1-32 characters.
33
+ */
34
+ export function looksLikeNimId(value: string): boolean {
35
+ if (!value || typeof value !== "string") {
36
+ return false;
37
+ }
38
+
39
+ const normalized = normalizeNimTarget(value);
40
+ if (!normalized) {
41
+ return false;
42
+ }
43
+
44
+ // NIM account IDs: alphanumeric, underscores, 1-32 chars
45
+ return /^[a-zA-Z0-9_]{1,32}$/.test(normalized);
46
+ }
47
+
48
+ /**
49
+ * Format a NIM target for display.
50
+ */
51
+ export function formatNimTarget(target: string): string {
52
+ const normalized = normalizeNimTarget(target);
53
+ if (!normalized) {
54
+ return target;
55
+ }
56
+ return `nim:${normalized}`;
57
+ }
58
+
59
+ /**
60
+ * Build a session ID for a P2P conversation.
61
+ */
62
+ export function buildP2pSessionId(account1: string, account2: string): string {
63
+ // NIM session IDs are typically "p2p-{targetAccount}"
64
+ return `p2p-${account2}`;
65
+ }
66
+
67
+ /**
68
+ * Parse a session ID to extract the target account.
69
+ */
70
+ export function parseSessionId(sessionId: string): { scene: "p2p" | "team"; targetId: string } | null {
71
+ if (!sessionId) {
72
+ return null;
73
+ }
74
+
75
+ if (sessionId.startsWith("p2p-")) {
76
+ return {
77
+ scene: "p2p",
78
+ targetId: sessionId.slice(4),
79
+ };
80
+ }
81
+
82
+ if (sessionId.startsWith("team-")) {
83
+ return {
84
+ scene: "team",
85
+ targetId: sessionId.slice(5),
86
+ };
87
+ }
88
+
89
+ // Assume P2P if no prefix
90
+ return {
91
+ scene: "p2p",
92
+ targetId: sessionId,
93
+ };
94
+ }
package/src/types.ts ADDED
@@ -0,0 +1,203 @@
1
+ /**
2
+ * NIM Types - node-nim SDK 版本
3
+ */
4
+
5
+ import type { NimConfigSchema } from "./config-schema.js";
6
+ import type { z } from "zod";
7
+
8
+ /**
9
+ * NIM 配置类型
10
+ */
11
+ export type NimConfig = z.infer<typeof NimConfigSchema>;
12
+
13
+ /**
14
+ * NIM 消息类型
15
+ */
16
+ export type NimMessageType =
17
+ | "text"
18
+ | "image"
19
+ | "audio"
20
+ | "video"
21
+ | "file"
22
+ | "geo"
23
+ | "notification"
24
+ | "custom"
25
+ | "tip"
26
+ | "robot"
27
+ | "unknown";
28
+
29
+ /**
30
+ * NIM 会话类型
31
+ */
32
+ export type NimSessionType = "p2p" | "team" | "superTeam";
33
+
34
+ /**
35
+ * NIM 消息事件(从 SDK 回调接收)
36
+ */
37
+ export interface NimMessageEvent {
38
+ /** 消息 ID */
39
+ msgId: string;
40
+ /** 消息客户端 ID */
41
+ clientMsgId: string;
42
+ /** 会话类型 */
43
+ sessionType: NimSessionType;
44
+ /** 发送者账号 */
45
+ from: string;
46
+ /** 接收者账号/群ID */
47
+ to: string;
48
+ /** 消息类型 */
49
+ type: NimMessageType;
50
+ /** 文本内容 */
51
+ text?: string;
52
+ /** 消息时间戳 (毫秒) */
53
+ time: number;
54
+ /** 附件信息 (图片/文件/音视频等) */
55
+ attach?: NimAttachment;
56
+ /** 扩展字段 */
57
+ ext?: Record<string, unknown>;
58
+ /** 原始消息对象 */
59
+ rawMsg?: unknown;
60
+ }
61
+
62
+ /**
63
+ * NIM 附件信息
64
+ */
65
+ export interface NimAttachment {
66
+ /** 文件名 */
67
+ name?: string;
68
+ /** 文件大小 */
69
+ size?: number;
70
+ /** 文件 URL */
71
+ url?: string;
72
+ /** 文件扩展名 */
73
+ ext?: string;
74
+ /** 文件 MD5 */
75
+ md5?: string;
76
+ /** 图片宽度 */
77
+ w?: number;
78
+ /** 图片高度 */
79
+ h?: number;
80
+ /** 音视频时长 (秒) */
81
+ dur?: number;
82
+ /** 地理位置标题 */
83
+ title?: string;
84
+ /** 纬度 */
85
+ lat?: number;
86
+ /** 经度 */
87
+ lng?: number;
88
+ }
89
+
90
+ /**
91
+ * NIM 消息上下文(业务层使用)
92
+ */
93
+ export interface NimMessageContext {
94
+ /** 唯一标识 */
95
+ id: string;
96
+ /** 会话 ID */
97
+ sessionId: string;
98
+ /** 会话类型 */
99
+ sessionType: NimSessionType;
100
+ /** 发送者 ID */
101
+ senderId: string;
102
+ /** 发送者名称 */
103
+ senderName?: string;
104
+ /** 消息类型 */
105
+ type: NimMessageType;
106
+ /** 文本内容 */
107
+ text: string;
108
+ /** 时间戳 */
109
+ timestamp: number;
110
+ /** 媒体附件 */
111
+ attachments?: NimMediaInfo[];
112
+ /** 是否为私聊 */
113
+ isDm: boolean;
114
+ /** 原始事件 */
115
+ rawEvent: NimMessageEvent;
116
+ }
117
+
118
+ /**
119
+ * NIM 媒体信息
120
+ */
121
+ export interface NimMediaInfo {
122
+ type: "image" | "file" | "audio" | "video";
123
+ url: string;
124
+ name?: string;
125
+ size?: number;
126
+ width?: number;
127
+ height?: number;
128
+ duration?: number;
129
+ localPath?: string;
130
+ }
131
+
132
+ /**
133
+ * NIM 发送结果
134
+ */
135
+ export interface NimSendResult {
136
+ success: boolean;
137
+ msgId?: string;
138
+ clientMsgId?: string;
139
+ error?: string;
140
+ errorCode?: number;
141
+ }
142
+
143
+ /**
144
+ * NIM 探测结果
145
+ */
146
+ export interface NimProbeResult {
147
+ connected: boolean;
148
+ account?: string;
149
+ error?: string;
150
+ loginState?: string;
151
+ }
152
+
153
+ /**
154
+ * NIM DM 策略
155
+ */
156
+ export type NimDmPolicy = "open" | "pairing" | "allowlist";
157
+
158
+ /**
159
+ * 解析后的 NIM 账户配置
160
+ */
161
+ export interface ResolvedNimAccount {
162
+ id: string;
163
+ appKey: string;
164
+ account: string;
165
+ token: string;
166
+ enabled: boolean;
167
+ dmPolicy: NimDmPolicy;
168
+ allowFrom: Array<string | number>;
169
+ }
170
+
171
+ /**
172
+ * NIM 客户端实例接口
173
+ */
174
+ export interface NimClientInstance {
175
+ /** 是否已初始化 */
176
+ initialized: boolean;
177
+ /** 是否已登录 */
178
+ loggedIn: boolean;
179
+ /** 当前账号 */
180
+ account: string;
181
+ /** 登录 */
182
+ login(): Promise<boolean>;
183
+ /** 登出 */
184
+ logout(): Promise<void>;
185
+ /** 发送文本消息 */
186
+ sendText(to: string, text: string, sessionType?: NimSessionType): Promise<NimSendResult>;
187
+ /** 发送图片消息 */
188
+ sendImage(to: string, filePath: string, sessionType?: NimSessionType): Promise<NimSendResult>;
189
+ /** 发送文件消息 */
190
+ sendFile(to: string, filePath: string, sessionType?: NimSessionType): Promise<NimSendResult>;
191
+ /** 发送音频消息 */
192
+ sendAudio(to: string, filePath: string, duration: number, sessionType?: NimSessionType): Promise<NimSendResult>;
193
+ /** 发送视频消息 */
194
+ sendVideo(to: string, filePath: string, duration: number, width: number, height: number, sessionType?: NimSessionType): Promise<NimSendResult>;
195
+ /** 注册消息回调 */
196
+ onMessage(callback: (msg: NimMessageEvent) => void): void;
197
+ /** 移除消息回调 */
198
+ offMessage(callback: (msg: NimMessageEvent) => void): void;
199
+ /** 注册连接状态回调 */
200
+ onConnectionChange(callback: (state: string) => void): void;
201
+ /** 销毁客户端 */
202
+ destroy(): Promise<void>;
203
+ }