@dcrays/dcgchat-test 0.5.0-alpha.2 → 0.5.0-alpha.4
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/index.js +292 -0
- package/package.json +7 -15
- package/schemas/gateway-cron-finished.payload.json +39 -0
- package/index.ts +0 -24
- package/src/agent.ts +0 -128
- package/src/bot.ts +0 -515
- package/src/channel.ts +0 -474
- package/src/cron.ts +0 -199
- package/src/cronToolCall.ts +0 -202
- package/src/gateway/cronFinishedPayload.ts +0 -118
- package/src/gateway/index.ts +0 -452
- package/src/gateway/security.ts +0 -95
- package/src/gateway/socket.ts +0 -285
- package/src/libs/ali-oss-6.23.0.tgz +0 -0
- package/src/libs/axios-1.13.6.tgz +0 -0
- package/src/libs/md5-2.3.0.tgz +0 -0
- package/src/libs/mime-types-3.0.2.tgz +0 -0
- package/src/libs/unzipper-0.12.3.tgz +0 -0
- package/src/libs/ws-8.19.0.tgz +0 -0
- package/src/monitor.ts +0 -165
- package/src/request/api.ts +0 -70
- package/src/request/oss.ts +0 -212
- package/src/request/request.ts +0 -192
- package/src/request/userInfo.ts +0 -93
- package/src/session.ts +0 -19
- package/src/sessionTermination.ts +0 -168
- package/src/skill.ts +0 -146
- package/src/tool.ts +0 -403
- package/src/tools/messageTool.ts +0 -273
- package/src/transport.ts +0 -206
- package/src/types.ts +0 -139
- package/src/utils/agentErrors.ts +0 -23
- package/src/utils/constant.ts +0 -7
- package/src/utils/gatewayMsgHanlder.ts +0 -84
- package/src/utils/global.ts +0 -161
- package/src/utils/log.ts +0 -15
- package/src/utils/params.ts +0 -88
- package/src/utils/searchFile.ts +0 -228
- package/src/utils/workspaceFilePaths.ts +0 -89
- package/src/utils/wsMessageHandler.ts +0 -64
- package/src/utils/zipExtract.ts +0 -97
- package/src/utils/zipPath.ts +0 -24
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcrays/dcgchat-test",
|
|
3
|
-
"version": "0.5.0-alpha.
|
|
3
|
+
"version": "0.5.0-alpha.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw channel plugin for 书灵墨宝 (WebSocket)",
|
|
6
|
-
"main": "index.
|
|
6
|
+
"main": "index.js",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"files": [
|
|
9
|
-
"index.
|
|
10
|
-
"
|
|
11
|
-
"schemas"
|
|
12
|
-
"openclaw.plugin.json"
|
|
9
|
+
"index.js",
|
|
10
|
+
"openclaw.plugin.json",
|
|
11
|
+
"schemas"
|
|
13
12
|
],
|
|
14
13
|
"keywords": [
|
|
15
14
|
"openclaw",
|
|
@@ -18,23 +17,16 @@
|
|
|
18
17
|
"ai"
|
|
19
18
|
],
|
|
20
19
|
"peerDependencies": {
|
|
21
|
-
"openclaw": ">=2026.4.
|
|
20
|
+
"openclaw": ">=2026.4.15"
|
|
22
21
|
},
|
|
23
22
|
"peerDependenciesMeta": {
|
|
24
23
|
"openclaw": {
|
|
25
24
|
"optional": true
|
|
26
25
|
}
|
|
27
26
|
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"ali-oss": "file:src/libs/ali-oss-6.23.0.tgz",
|
|
30
|
-
"axios": "file:src/libs/axios-1.13.6.tgz",
|
|
31
|
-
"md5": "file:src/libs/md5-2.3.0.tgz",
|
|
32
|
-
"unzipper": "file:src/libs/unzipper-0.12.3.tgz",
|
|
33
|
-
"ws": "file:src/libs/ws-8.19.0.tgz"
|
|
34
|
-
},
|
|
35
27
|
"openclaw": {
|
|
36
28
|
"extensions": [
|
|
37
|
-
"./index.
|
|
29
|
+
"./index.js"
|
|
38
30
|
],
|
|
39
31
|
"channel": {
|
|
40
32
|
"id": "dcgchat-test",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://dcgchat.local/schemas/gateway-cron-finished.payload.json",
|
|
4
|
+
"title": "Gateway WS event: cron finished (dcgchat contract)",
|
|
5
|
+
"description": "网关下行 `event: \"cron\"` 且 `payload.action === \"finished\"` 时,书灵通道插件读取的约定字段。`attachments` 为首选:须为 Gateway 进程可读的绝对路径,经通道 sendMedia 发送。若宿主未提供 `attachments`,插件会回退为仅在工作区/挂载规则下从 `summary` 提取路径(与 dcgchat_message 一致),直至宿主实现本字段。",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"jobId": { "type": "string" },
|
|
9
|
+
"action": { "const": "finished" },
|
|
10
|
+
"status": { "type": "string" },
|
|
11
|
+
"summary": { "type": "string" },
|
|
12
|
+
"delivered": { "type": "boolean" },
|
|
13
|
+
"deliveryStatus": { "type": "string" },
|
|
14
|
+
"sessionId": { "type": "string" },
|
|
15
|
+
"sessionKey": { "type": "string" },
|
|
16
|
+
"attachments": {
|
|
17
|
+
"type": "array",
|
|
18
|
+
"description": "本轮定时任务产出的本地文件路径,按顺序经通道发送为附件",
|
|
19
|
+
"items": {
|
|
20
|
+
"oneOf": [
|
|
21
|
+
{
|
|
22
|
+
"type": "string",
|
|
23
|
+
"minLength": 1,
|
|
24
|
+
"description": "绝对路径"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"properties": {
|
|
30
|
+
"path": { "type": "string", "minLength": 1 },
|
|
31
|
+
"file": { "type": "string", "minLength": 1 }
|
|
32
|
+
},
|
|
33
|
+
"description": "对象形式:优先读取 `path`,否则 `file`"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineChannelPluginEntry } from 'openclaw/plugin-sdk/core'
|
|
2
|
-
import { dcgchatPlugin } from './src/channel.js'
|
|
3
|
-
import { setDcgchatRuntime, setWorkspaceDir } from './src/utils/global.js'
|
|
4
|
-
import { monitoringToolMessage } from './src/tool.js'
|
|
5
|
-
import { setOpenClawConfig } from './src/utils/global.js'
|
|
6
|
-
import { createDcgchatMessageTool } from './src/tools/messageTool.js'
|
|
7
|
-
|
|
8
|
-
export default defineChannelPluginEntry({
|
|
9
|
-
id: "dcgchat-test",
|
|
10
|
-
name: '书灵墨宝',
|
|
11
|
-
description: '连接 OpenClaw 与 书灵墨宝 产品(WebSocket)',
|
|
12
|
-
plugin: dcgchatPlugin,
|
|
13
|
-
setRuntime: (runtime) => {
|
|
14
|
-
setDcgchatRuntime(runtime)
|
|
15
|
-
},
|
|
16
|
-
registerFull: (api) => {
|
|
17
|
-
monitoringToolMessage(api)
|
|
18
|
-
setOpenClawConfig(api.config)
|
|
19
|
-
setWorkspaceDir(api.config?.agents?.defaults?.workspace)
|
|
20
|
-
api.registerTool((ctx) => {
|
|
21
|
-
return createDcgchatMessageTool(ctx)
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
})
|
package/src/agent.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import axios from 'axios'
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import { getWorkspaceDir } from './utils/global.js'
|
|
5
|
-
import { getWsConnection } from './utils/global.js'
|
|
6
|
-
import { dcgLogger } from './utils/log.js'
|
|
7
|
-
import { isWsOpen } from './transport.js'
|
|
8
|
-
import { sendMessageToGateway } from './gateway/socket.js'
|
|
9
|
-
import { extractZipBufferToDirectory } from './utils/zipExtract.js'
|
|
10
|
-
|
|
11
|
-
type IAgentParams = {
|
|
12
|
-
url: string
|
|
13
|
-
agent_code: string
|
|
14
|
-
agent_name: string
|
|
15
|
-
agent_description: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function sendEvent(msgContent: Record<string, any>) {
|
|
19
|
-
const ws = getWsConnection()
|
|
20
|
-
if (isWsOpen()) {
|
|
21
|
-
ws?.send(
|
|
22
|
-
JSON.stringify({
|
|
23
|
-
messageType: 'openclaw_bot_event',
|
|
24
|
-
source: 'client',
|
|
25
|
-
content: msgContent
|
|
26
|
-
})
|
|
27
|
-
)
|
|
28
|
-
dcgLogger(`agent安装: ${JSON.stringify(msgContent)}`)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** 若 workspace-${clone_code}/agent 存在,则复制到 agents/${clone_code}/agent */
|
|
33
|
-
function copyAgentsFiles(clone_code: string) {
|
|
34
|
-
const workspacePath = getWorkspaceDir()
|
|
35
|
-
if (!workspacePath) return
|
|
36
|
-
const workspaceDir = path.join(workspacePath, '../', `workspace-${clone_code}`)
|
|
37
|
-
const agentDir = path.join(workspacePath, '../', `agents/${clone_code}`)
|
|
38
|
-
const sourceAgent = path.join(workspaceDir, 'agent')
|
|
39
|
-
try {
|
|
40
|
-
if (!fs.existsSync(sourceAgent)) return
|
|
41
|
-
if (!fs.statSync(sourceAgent).isDirectory()) return
|
|
42
|
-
fs.mkdirSync(agentDir, { recursive: true })
|
|
43
|
-
const dest = path.join(agentDir, 'agent')
|
|
44
|
-
if (fs.existsSync(dest)) {
|
|
45
|
-
fs.rmSync(dest, { recursive: true, force: true })
|
|
46
|
-
}
|
|
47
|
-
fs.cpSync(sourceAgent, dest, { recursive: true })
|
|
48
|
-
} catch (err: unknown) {
|
|
49
|
-
dcgLogger(`copyAgentsFiles failed: ${String(err)}`, 'error')
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export async function onCreateAgent(params: Record<string, any>) {
|
|
54
|
-
const { clone_code, name, description } = params
|
|
55
|
-
try {
|
|
56
|
-
const workspacePath = getWorkspaceDir()
|
|
57
|
-
if (!workspacePath) return
|
|
58
|
-
const workspaceDir = path.join(workspacePath, '../', `workspace-${clone_code}`)
|
|
59
|
-
await sendMessageToGateway(JSON.stringify({ method: 'agents.create', params: { name: clone_code, workspace: workspaceDir } }))
|
|
60
|
-
} catch (err: unknown) {
|
|
61
|
-
dcgLogger(`agents.create failed: ${String(err)}`, 'error')
|
|
62
|
-
}
|
|
63
|
-
// Update config.name to the user-supplied display name (may contain CJK, spaces, etc.)
|
|
64
|
-
try {
|
|
65
|
-
await sendMessageToGateway(JSON.stringify({ method: 'agents.update', params: { name: name, agentId: clone_code } }))
|
|
66
|
-
} catch (err: unknown) {
|
|
67
|
-
dcgLogger(`agents.update failed: ${String(err)}`, 'error')
|
|
68
|
-
}
|
|
69
|
-
// if (description?.trim()) {
|
|
70
|
-
// try {
|
|
71
|
-
// await sendMessageToGateway(
|
|
72
|
-
// JSON.stringify({
|
|
73
|
-
// method: 'agents.files.set',
|
|
74
|
-
// params: { agentId: clone_code, name: 'IDENTITY.md', content: description.trim() }
|
|
75
|
-
// })
|
|
76
|
-
// )
|
|
77
|
-
// } catch {
|
|
78
|
-
// // Non-fatal
|
|
79
|
-
// }
|
|
80
|
-
// }
|
|
81
|
-
// if (name?.trim()) {
|
|
82
|
-
// try {
|
|
83
|
-
// await sendMessageToGateway(
|
|
84
|
-
// JSON.stringify({
|
|
85
|
-
// method: 'agents.files.set',
|
|
86
|
-
// params: { agentId: clone_code, name: 'USER.md', content: name.trim() }
|
|
87
|
-
// })
|
|
88
|
-
// )
|
|
89
|
-
// } catch {
|
|
90
|
-
// // Non-fatal
|
|
91
|
-
// }
|
|
92
|
-
// }
|
|
93
|
-
copyAgentsFiles(clone_code)
|
|
94
|
-
sendEvent({ ...params, status: 'ok' })
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function createAgent(msgContent: Record<string, any>) {
|
|
98
|
-
const { url, clone_code } = msgContent
|
|
99
|
-
if (!url || !clone_code) {
|
|
100
|
-
dcgLogger(`createAgent failed empty url&clone_code: ${JSON.stringify(msgContent)}`, 'error')
|
|
101
|
-
sendEvent({ ...msgContent, status: 'fail' })
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
const workspacePath = getWorkspaceDir()
|
|
105
|
-
const workspaceDir = path.join(workspacePath, '../', `workspace-${clone_code}`)
|
|
106
|
-
|
|
107
|
-
// 如果目标目录已存在,先删除
|
|
108
|
-
if (fs.existsSync(workspaceDir)) {
|
|
109
|
-
fs.rmSync(workspaceDir, { recursive: true, force: true })
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
const response = await axios({
|
|
114
|
-
method: 'get',
|
|
115
|
-
url,
|
|
116
|
-
responseType: 'arraybuffer'
|
|
117
|
-
})
|
|
118
|
-
fs.mkdirSync(workspaceDir, { recursive: true })
|
|
119
|
-
await extractZipBufferToDirectory(Buffer.from(response.data), workspaceDir)
|
|
120
|
-
await onCreateAgent(msgContent)
|
|
121
|
-
} catch (error) {
|
|
122
|
-
// 如果安装失败,清理目录
|
|
123
|
-
if (fs.existsSync(workspaceDir)) {
|
|
124
|
-
fs.rmSync(workspaceDir, { recursive: true, force: true })
|
|
125
|
-
}
|
|
126
|
-
sendEvent({ ...msgContent, status: 'fail' })
|
|
127
|
-
}
|
|
128
|
-
}
|