@dcrays/dcgchat-test 0.2.22 → 0.2.23

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.
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "id": "dcgchat-test",
3
- "channels": ["dcgchat-test"],
3
+ "channels": [
4
+ "dcgchat-test"
5
+ ],
4
6
  "configSchema": {
5
7
  "type": "object",
6
8
  "additionalProperties": false,
7
9
  "properties": {}
8
10
  }
9
- }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/dcgchat-test",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "type": "module",
5
5
  "description": "OpenClaw channel plugin for 书灵墨宝 (WebSocket)",
6
6
  "main": "index.ts",
@@ -17,7 +17,9 @@
17
17
  "ai"
18
18
  ],
19
19
  "scripts": {
20
- "typecheck": "tsc --noEmit"
20
+ "typecheck": "tsc --noEmit",
21
+ "build:prod": "npx tsx scripts/build.ts production",
22
+ "build:test": "npx tsx scripts/build.ts test"
21
23
  },
22
24
  "dependencies": {
23
25
  "ali-oss": "file:src/libs/ali-oss-6.23.0.tgz",
@@ -34,18 +36,15 @@
34
36
  "id": "dcgchat-test",
35
37
  "label": "书灵墨宝",
36
38
  "selectionLabel": "书灵墨宝",
37
- "docsPath": "/channels/dcgchat",
39
+ "docsPath": "/channels/dcgchat-test",
38
40
  "docsLabel": "dcgchat-test",
39
41
  "blurb": "连接 OpenClaw 与 书灵墨宝 产品",
40
42
  "order": 80
41
43
  },
42
44
  "install": {
43
45
  "npmSpec": "@dcrays/dcgchat-test",
44
- "localPath": "extensions/dcgchat",
46
+ "localPath": "extensions/dcgchat-test",
45
47
  "defaultChoice": "npm"
46
48
  }
47
- },
48
- "devDependencies": {
49
- "openclaw": "^2026.3.13"
50
49
  }
51
- }
50
+ }
package/src/bot.ts CHANGED
@@ -428,9 +428,9 @@ export async function handleDcgchatMessage(params: {
428
428
 
429
429
  log(`dcgchat[${accountId}]: ctxPayload=${JSON.stringify(ctxPayload)}`);
430
430
 
431
- const sentMediaKeys = new Set<string>();
432
- const getMediaKey = (url: string) => url.split(/[\\/]/).pop() ?? url;
433
- let textChunk = "";
431
+ const sentMediaKeys = new Set<string>()
432
+ const getMediaKey = (url: string) => url.split(/[\\/]/).pop() ?? url
433
+ let textChunk = ''
434
434
 
435
435
  const prefixContext = createReplyPrefixContext({
436
436
  cfg,
package/src/channel.ts CHANGED
@@ -114,7 +114,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
114
114
  id: "dcgchat-test",
115
115
  label: "书灵墨宝",
116
116
  selectionLabel: "书灵墨宝",
117
- docsPath: "/channels/dcgchat",
117
+ docsPath: "/channels/dcgchat-test",
118
118
  docsLabel: "dcgchat-test",
119
119
  blurb: "连接 OpenClaw 与 书灵墨宝 产品",
120
120
  order: 80,
@@ -131,7 +131,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
131
131
  effects: true,
132
132
  // blockStreaming: true,
133
133
  },
134
- reload: { configPrefixes: ["channels.dcgchat"] },
134
+ reload: { configPrefixes: ["channels.dcgchat-test"] },
135
135
  configSchema: {
136
136
  schema: {
137
137
  type: "object",
package/src/skill.ts CHANGED
@@ -5,15 +5,24 @@ import unzipper from 'unzipper';
5
5
  import { pipeline } from "stream/promises";
6
6
  import fs from 'fs';
7
7
  import path from 'path';
8
+ import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk";
8
9
  import { logDcgchat } from './log.js';
9
- import { getWorkspaceDir } from './runtime.js';
10
+ import { getDcgchatRuntime, getWorkspaceDir } from './runtime.js';
10
11
  import { getWsConnection } from './connection.js';
12
+ import { resolveAccount } from './channel.js';
13
+ import { getMsgParams } from './tool.js';
11
14
 
12
15
  type ISkillParams = {
13
16
  path: string;
14
17
  code: string;
15
18
  }
16
19
 
20
+ type SkillContext = {
21
+ cfg: ClawdbotConfig;
22
+ accountId: string;
23
+ runtime?: RuntimeEnv;
24
+ }
25
+
17
26
  function sendEvent(msgContent: Record<string, any>) {
18
27
  const ws = getWsConnection()
19
28
  if (ws?.readyState === WebSocket.OPEN) {
@@ -27,7 +36,77 @@ function sendEvent(msgContent: Record<string, any>) {
27
36
  }
28
37
  }
29
38
 
30
- export async function installSkill(params: ISkillParams, msgContent: Record<string, any>) {
39
+ // async function sendNewSessionCommand(ctx: SkillContext) {
40
+ // try {
41
+ // const core = getDcgchatRuntime();
42
+ // const log = ctx.runtime?.log ?? console.log;
43
+ // const params = getMsgParams();
44
+ // const account = resolveAccount(ctx.cfg, ctx.accountId);
45
+ // const userId = String(params.userId);
46
+
47
+ // const route = core.channel.routing.resolveAgentRoute({
48
+ // cfg: ctx.cfg,
49
+ // channel: "dcgchat-test",
50
+ // accountId: account.accountId,
51
+ // peer: { kind: "direct", id: userId },
52
+ // });
53
+
54
+ // const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(ctx.cfg);
55
+ // const bodyFormatted = core.channel.reply.formatAgentEnvelope({
56
+ // channel: "书灵墨宝",
57
+ // from: userId,
58
+ // timestamp: new Date(),
59
+ // envelope: envelopeOptions,
60
+ // body: "/new",
61
+ // });
62
+
63
+ // const ctxPayload = core.channel.reply.finalizeInboundContext({
64
+ // Body: bodyFormatted,
65
+ // RawBody: "/new",
66
+ // CommandBody: "/new",
67
+ // From: userId,
68
+ // To: userId,
69
+ // SessionKey: route.sessionKey,
70
+ // AccountId: params.sessionId,
71
+ // ChatType: "direct",
72
+ // SenderName: userId,
73
+ // SenderId: userId,
74
+ // Provider: "dcgchat-test" as const,
75
+ // Surface: "dcgchat-test" as const,
76
+ // MessageSid: Date.now().toString(),
77
+ // Timestamp: Date.now(),
78
+ // WasMentioned: true,
79
+ // CommandAuthorized: true,
80
+ // OriginatingChannel: "dcgchat-test" as const,
81
+ // OriginatingTo: `user:${userId}`,
82
+ // });
83
+
84
+ // const noopDispatcher = {
85
+ // sendToolResult: () => false,
86
+ // sendBlockReply: () => false,
87
+ // sendFinalReply: () => false,
88
+ // waitForIdle: async () => {},
89
+ // getQueuedCounts: () => ({ tool: 0, block: 0, final: 0 }),
90
+ // markComplete: () => {},
91
+ // };
92
+
93
+ // await core.channel.reply.withReplyDispatcher({
94
+ // dispatcher: noopDispatcher,
95
+ // run: () =>
96
+ // core.channel.reply.dispatchReplyFromConfig({
97
+ // ctx: ctxPayload,
98
+ // cfg: ctx.cfg,
99
+ // dispatcher: noopDispatcher,
100
+ // }),
101
+ // });
102
+
103
+ // log(`dcgchat: /new command dispatched silently after skill install`);
104
+ // } catch (err) {
105
+ // logDcgchat.error(`sendNewSessionCommand failed: ${err}`);
106
+ // }
107
+ // }
108
+
109
+ export async function installSkill(params: ISkillParams, msgContent: Record<string, any>, ctx?: SkillContext) {
31
110
  const { path: cdnUrl, code } = params;
32
111
  const workspacePath = getWorkspaceDir();
33
112
 
@@ -129,6 +208,9 @@ export async function installSkill(params: ISkillParams, msgContent: Record<stri
129
208
  });
130
209
  });
131
210
  sendEvent({ ...msgContent, status: 'ok' })
211
+ // if (ctx) {
212
+ // await sendNewSessionCommand(ctx);
213
+ // }
132
214
  } catch (error) {
133
215
  // 如果安装失败,清理目录
134
216
  if (fs.existsSync(skillDir)) {
package/README.md DELETED
@@ -1,83 +0,0 @@
1
- # OpenClaw 书灵墨宝 插件
2
-
3
- 连接 OpenClaw 与 书灵墨宝 产品的通道插件。
4
-
5
- ## 架构
6
-
7
- ```
8
- ┌──────────┐ WebSocket ┌──────────────┐ WebSocket ┌─────────────────────┐
9
- │ Web 前端 │ ←───────────────→ │ 公司后端服务 │ ←───────────────→ │ OpenClaw(工作电脑) │
10
- └──────────┘ └──────────────┘ (OpenClaw 主动连) └─────────────────────┘
11
- ```
12
-
13
- - OpenClaw 插件**主动连接**后端的 WebSocket 服务(不需要公网 IP)
14
- - 后端收到用户消息后转发给 OpenClaw,OpenClaw 回复后发回后端
15
-
16
- ## 快速开始
17
-
18
- ### 1. 安装插件
19
-
20
- ```bash
21
- pnpm openclaw plugins install -l /path/to/openclaw-dcgchat
22
- ```
23
-
24
- ### 2. 配置
25
-
26
- ```bash
27
- openclaw config set channels.dcgchat.enabled true
28
- openclaw config set channels.dcgchat.wsUrl "ws://your-backend:8080/openclaw/ws"
29
- ```
30
-
31
- ### 3. 启动
32
-
33
- ```bash
34
- pnpm openclaw gateway
35
- ```
36
-
37
- ## 消息协议(MVP)
38
-
39
- ### 下行:后端 → OpenClaw(用户消息)
40
-
41
- ```json
42
- { "type": "message", "userId": "user_001", "text": "你好" }
43
- ```
44
-
45
- ### 上行:OpenClaw → 后端(Agent 回复)
46
-
47
- ```json
48
- { "type": "reply", "userId": "user_001", "text": "你好!有什么可以帮你的?" }
49
- ```
50
-
51
- ## 配置项
52
-
53
- | 配置键 | 类型 | 说明 |
54
- |--------|------|------|
55
- | `channels.dcgchat.enabled` | boolean | 是否启用 |
56
- | `channels.dcgchat.wsUrl` | string | 后端 WebSocket 地址 |
57
-
58
- ## 开发
59
-
60
- ```bash
61
- # 安装依赖
62
- pnpm install
63
-
64
- # 类型检查
65
- pnpm typecheck
66
- ```
67
-
68
- ## 文件结构
69
-
70
- - `index.ts` - 插件入口
71
- - `src/channel.ts` - ChannelPlugin 定义
72
- - `src/runtime.ts` - 插件 runtime
73
- - `src/types.ts` - 类型定义
74
- - `src/monitor.ts` - WebSocket 连接与断线重连
75
- - `src/bot.ts` - 消息处理与 Agent 调用
76
-
77
- ## 后续迭代
78
-
79
- - [ ] Token 认证
80
- - [ ] 流式输出
81
- - [ ] Typing 指示
82
- - [ ] messageId 去重
83
- - [ ] 错误消息类型