@ctyun/desktop-agent-sdk 0.0.1 → 0.0.2
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 +11 -93
- package/dist/index.cjs.js +2 -2
- package/dist/index.esm.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ pnpm add @ctyun/desktop-agent-sdk
|
|
|
33
33
|
|
|
34
34
|
## 基本使用方法
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### 1、 创建 Client 实例
|
|
37
37
|
|
|
38
38
|
首先导入并创建 Client 实例。创建实例时需要提供以下参数:
|
|
39
39
|
|
|
@@ -53,7 +53,7 @@ const client = new Client({
|
|
|
53
53
|
});
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
###
|
|
56
|
+
### 2、 创建会话
|
|
57
57
|
|
|
58
58
|
使用 `createSession()` 方法创建会话,会话创建成功后将返回会话对象,包含 sessionId 和操作方法。
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ const session = await client.createSession();
|
|
|
62
62
|
console.log('会话创建成功,sessionId:', session.sessionId);
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
### 3
|
|
65
|
+
### 3、 使用 computer 方法
|
|
66
66
|
|
|
67
67
|
创建会话后,可以通过 `session.computer` 对象调用各种计算机控制方法。
|
|
68
68
|
|
|
@@ -141,20 +141,7 @@ await session.computer.screen_shot();
|
|
|
141
141
|
await session.computer.get_cursor_position();
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
###
|
|
145
|
-
|
|
146
|
-
对于异步执行的操作,可以使用 `query_job()` 方法查询任务执行状态和结果。
|
|
147
|
-
|
|
148
|
-
```javascript
|
|
149
|
-
// 假设某个操作返回了 jobId
|
|
150
|
-
const jobId = 'your-job-id';
|
|
151
|
-
|
|
152
|
-
// 查询任务状态
|
|
153
|
-
const result = await session.query_job(jobId);
|
|
154
|
-
console.log('任务状态:', result);
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### 3.5 关闭会话
|
|
144
|
+
### 4、 关闭会话
|
|
158
145
|
|
|
159
146
|
使用完成后,应该关闭会话以释放资源。
|
|
160
147
|
|
|
@@ -202,7 +189,7 @@ async function main() {
|
|
|
202
189
|
main();
|
|
203
190
|
```
|
|
204
191
|
|
|
205
|
-
##
|
|
192
|
+
## API 参考
|
|
206
193
|
|
|
207
194
|
### Client 类
|
|
208
195
|
|
|
@@ -237,7 +224,6 @@ async createSession(): Promise<Session>
|
|
|
237
224
|
|--------|------|------|
|
|
238
225
|
| sessionId | string | 会话唯一标识 |
|
|
239
226
|
| computer | ComputerAPI | 计算机控制方法集合 |
|
|
240
|
-
| query_job | Function | 查询任务状态方法 |
|
|
241
227
|
| close | Function | 关闭会话方法 |
|
|
242
228
|
|
|
243
229
|
### Session 对象
|
|
@@ -249,28 +235,15 @@ async createSession(): Promise<Session>
|
|
|
249
235
|
``` json
|
|
250
236
|
{
|
|
251
237
|
"code": 0,
|
|
252
|
-
"data":
|
|
253
|
-
|
|
254
|
-
"sessionId": "",
|
|
255
|
-
"desktopCode": "",
|
|
256
|
-
"jobId": "",
|
|
257
|
-
"jobStatus": 1,
|
|
258
|
-
"jobRollInterval": 100,
|
|
259
|
-
"jobRollTimes": 16
|
|
260
|
-
}
|
|
238
|
+
"data":null,
|
|
239
|
+
"msg":null
|
|
261
240
|
}
|
|
262
241
|
```
|
|
263
242
|
| 参数名 | 类型 | 说明 |
|
|
264
243
|
|--------|------|------|
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
|
268
|
-
| jobId | number | 本次请求的任务ID,用于后续轮询查看结果 |
|
|
269
|
-
| jobStatus | number | 任务状态:<br/>-1:未响应<br/> 1:接收成功<br/>2:接收失败<br/>3:执行成功<br/>4:执行失败|
|
|
270
|
-
| jobRollIntervalMs | number | 建议的轮询间隔,单位:ms |
|
|
271
|
-
| jobRollTimes | number | 建议的轮询次数 |
|
|
272
|
-
|
|
273
|
-
你可以通过这里返回的`jobId`轮询调用query_job方法,拿到对应操作的执行结果。
|
|
244
|
+
| code | number | 状态码,为`0`代表成功,其他表示失败 |
|
|
245
|
+
| data | number | 结果,code为`0`时不为空 |
|
|
246
|
+
| msg | number | code不为`0`时记录错误信息 |
|
|
274
247
|
|
|
275
248
|
##### move_mouse(x, y)
|
|
276
249
|
|
|
@@ -289,7 +262,7 @@ async createSession(): Promise<Session>
|
|
|
289
262
|
|--------|------|------|------|
|
|
290
263
|
| x | number | 是 | X 坐标 |
|
|
291
264
|
| y | number | 是 | Y 坐标 |
|
|
292
|
-
| clickMode | string | 否 | 点击模式:`'left'`(默认)、`'right'`、`'middle'` |
|
|
265
|
+
| clickMode | string | 否 | 点击模式:`'left'`(默认)、`'right'`、`'middle'`、`double_left` |
|
|
293
266
|
| pressMode | string | 否 | 按下模式:`'down'`、`'up'`,不传则按下并释放 |
|
|
294
267
|
|
|
295
268
|
##### press_mouse(x, y, pressMode?)
|
|
@@ -354,65 +327,10 @@ async createSession(): Promise<Session>
|
|
|
354
327
|
|
|
355
328
|
截取屏幕。
|
|
356
329
|
|
|
357
|
-
**返回值:**
|
|
358
|
-
通过query_job轮询查询结果
|
|
359
|
-
|
|
360
330
|
##### get_cursor_position()
|
|
361
331
|
|
|
362
332
|
获取当前鼠标位置。
|
|
363
333
|
|
|
364
|
-
**返回值:**
|
|
365
|
-
通过query_job轮询查询结果
|
|
366
|
-
|
|
367
|
-
- #### query_job(jobId)
|
|
368
|
-
|
|
369
|
-
查询异步任务执行结果。
|
|
370
|
-
|
|
371
|
-
| 参数名 | 类型 | 说明 |
|
|
372
|
-
|--------|------|------|
|
|
373
|
-
| jobId | string | 任务 ID |
|
|
374
|
-
|
|
375
|
-
**返回值:**
|
|
376
|
-
``` json
|
|
377
|
-
{
|
|
378
|
-
"code": 0,
|
|
379
|
-
"data": {
|
|
380
|
-
"requestId": "",
|
|
381
|
-
"desktopCode": "",
|
|
382
|
-
"sessionId": "",
|
|
383
|
-
"jobId": "",
|
|
384
|
-
"jobStatus": 1,
|
|
385
|
-
"resp": ""
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
| 参数名 | 类型 | 说明 |
|
|
390
|
-
|--------|------|------|
|
|
391
|
-
| requestId | string | 本次请求的ID |
|
|
392
|
-
| sessionId | number | 会话ID,同`createSession`返回值相同 |
|
|
393
|
-
| desktopCode | number | 桌面编码 |
|
|
394
|
-
| jobId | number | 本次查询的任务ID |
|
|
395
|
-
| jobStatus | number | 任务状态:<br/>-1:未响应<br/> 1:接收成功<br/>2:接收失败<br/>3:执行成功<br/>4:执行失败|
|
|
396
|
-
| resp | string | 操作的执行结果返回值 |
|
|
397
|
-
|
|
398
|
-
**示例:** 执行屏幕截图
|
|
399
|
-
``` javascript
|
|
400
|
-
...创建client和session
|
|
401
|
-
const res = await session.computer.screen_shot();
|
|
402
|
-
const {jobId,jobRollIntervalMs,jobRollTimes}=res.data
|
|
403
|
-
|
|
404
|
-
let n_roll_times=0
|
|
405
|
-
const do_query_job=async ()=>{
|
|
406
|
-
if(n_roll_times>jobRollTimes) return
|
|
407
|
-
const result=await session.query_job(jobId)
|
|
408
|
-
const {jobStatus,resp}=result.data
|
|
409
|
-
if(resp) console.log("操作结果是:"+resp)
|
|
410
|
-
else setTimeout(()=>do_query_job(),jobRollIntervalMs)
|
|
411
|
-
}
|
|
412
|
-
setTimeout(()=>do_query_job(),jobRollIntervalMs)
|
|
413
|
-
|
|
414
|
-
```
|
|
415
|
-
|
|
416
334
|
- #### close()
|
|
417
335
|
|
|
418
336
|
关闭当前会话。
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @ctyun/desktop-agent-sdk v0.0.
|
|
2
|
-
"use strict";var e=require("axios"),s=require("node:crypto");const t=e.create({baseURL:
|
|
1
|
+
/*! @ctyun/desktop-agent-sdk v0.0.2 | (c) 2026-02-13 zhangjiliang | https://desk.ctyun.cn/html/download/ */
|
|
2
|
+
"use strict";var e=require("axios"),s=require("node:crypto");const t=e.create({});[t].forEach(e=>{e.interceptors.request.use(e=>(e=>{const s={baseURL:e.baseURL,url:e.url,payload:e.data},t=Object.keys(e.headers).reduce((s,t)=>(s[t]=e.headers[t],s),{});return s.headers=t,console.log(JSON.stringify(s,null,2)),e})(e)),e.interceptors.response.use(e=>(e=>{const s={url:e.config.url,response:e.data};return console.log(JSON.stringify(s,null,2)),e})(e),e=>(e=>{const s={url:err.config.url,response:e.response.data||{}};return console.error(JSON.stringify(s,null,2)),e})(e))});var o={createSeesion:function(e,s){return t.post("/api/openApi/cdserv/aiUse/createSession",e,{...s})},sendMessage:function(e,s){return t.post("/api/openApi/cdserv/aiUse/sendMessage",e,{...s})},queryJob:function(e,s){return t.post("/api/openApi/cdserv/aiUse/queryJob",e,{...s})},deleteSession:function(e,s){return t.post("/api/openApi/cdserv/aiUse/deleteSession",e,{...s})}};const r=e=>{const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",o=s.randomBytes(e);let r="";for(let e=0;e<o.length;e++)r+=t[o[e]%62];return r.slice(0,e)},a=e=>{const{path:t,body:o,apiKey:a,apiSecret:n}=e;let i={};const c=t.indexOf("?");-1!==c&&(i=(e=>{if(!e)return{};let s={},t=e.split("&");for(let e=0;e<t.length;e++){let o=t[e].split("=");s[o[0]]=o[1]}return s})(t.slice(c+1)));const d={"x-ctg-ecpc-ak":a,"x-ctg-algorithm":"SHA256","x-ctg-timestamp":(new Date).getTime(),"x-ctg-nonStr":r(8)};o&&(d["x-ctg-reqJson"]=(e=>{const t=s.createHash("md5");return t.update(e),t.digest("hex")})(JSON.stringify(o)));const u=Object.assign({},i,d),p=[],l=Object.keys(u);l.sort(),l.forEach(e=>{p.push(`${e}=${u[e]}`)});const h=p.join("&")+n;return d.sign=(e=>{const t=s.createHash("sha256");return t.update(e),t.digest("hex")})(h),d},n=(e,t)=>{const o=s.createCipheriv("aes-256-cbc",t,"0000000000000000");let r=o.update(e,"utf8","base64");return r+=o.final("base64"),r};var i=Object.freeze({__proto__:null,click_mouse:(e,s,t="left",o="down")=>({action:"ClickMouse",params:{PositionX:e,PositionY:s,Button:t,Press:"down"==o,Release:"up"==o}}),drag_mouse:(e,s,t,o)=>({action:"DragMouse",params:{SourceX:e,SourceY:s,TargetX:t,TargetY:o}}),get_cursor_position:()=>({action:"GetCursorPosition"}),move_mouse:(e,s)=>({action:"MoveMouse",params:{PositionX:e,PositionY:s}}),press_key:e=>({action:"PressKey",params:{Key:e}}),press_mouse:(e,s,t="left")=>({action:"PressMouse",params:{PositionX:e,PositionY:s,Button:t}}),release_mouse:(e,s,t="left")=>({action:"ReleaseMouse",params:{PositionX:e,PositionY:s,Button:t}}),screen_shot:()=>({action:"TakeScreenshot"}),scroll:(e,s,t,o)=>({action:"Scroll",params:{PositionX:e,PositionY:s,Direction:t,Amount:o}}),type_text:e=>({action:"TypeText",params:{Text:e}})});const c=(e,s)=>{const{apiKey:t,apiSecret:o,path:r}=s;return{headers:a({path:r||"",body:e,apiKey:t,apiSecret:o}),body:e}};module.exports=class{constructor(e={}){this.options=Object.assign({serviceURL:"https://desk.ctyun.cn:8816"},e);const{apiKey:s,apiSecret:t,desktopCode:o,serviceURL:r}=this.options;if(!s||!t)throw new Error("apiKey或apiSecret不能为空");if(!r)throw new Error("serviceURL不能为空");if(!o)throw new Error("desktopCode不能为空")}async createSession(){const{apiKey:e,apiSecret:s,desktopCode:t,serviceURL:a}=this.options,d={requestId:r(32),desktopCode:t},{headers:u,body:p}=c(d,{apiKey:e,apiSecret:s}),l=await o.createSeesion(p,{headers:u,baseURL:a}),h=this.sessionId=l.data.data.sessionId,y=Object.keys(i).reduce((d,u)=>(d[u]=async(...d)=>{if(!this.sessionId)throw new Error("会话已关闭或未创建");const p=i[u](...d),l=r(32),y={requestId:l,desktopCode:t,sessionId:h,message:n(JSON.stringify(p),l)},{headers:m,body:f}=c(y,{apiKey:e,apiSecret:s}),b=await o.sendMessage(f,{headers:m,baseURL:a}),S=()=>{const{jobId:e,jobRollIntervalMs:s,jobRollTimes:t}=b.data.data;return new Promise((o,r)=>{let a=0;const n=async()=>{if(a++,!this.sessionId)return r({code:-1,data:null,msg:"会话已关闭"});if(a>t)return r({code:-1,data:null,msg:"已超时"});const i=(new Date).getTime();try{const t=await g(e),r=(new Date).getTime(),a=r-i>=s?0:s-(r-i);if(0==t.data.code){const{resp:e,respFlag:s}=t.data.data;s?o({code:0,data:e,msg:null}):setTimeout(()=>n(),a)}else setTimeout(()=>n(),a)}catch(e){const t=(new Date).getTime();setTimeout(()=>n(),t-i>=s?0:s-(t-i))}};setTimeout(()=>n(),s)})};if(0==b.data.code){return await S()}return{code:code,data:null,msg:"发送失败"}},d),{}),g=async n=>{if(!this.sessionId)throw new Error("会话已关闭或未创建");const i={requestId:r(32),desktopCode:t,sessionId:h,jobId:n},{headers:d,body:u}=c(i,{apiKey:e,apiSecret:s});return(await o.queryJob(u,{headers:d,baseURL:a})).data},m={sessionId:h,close:async()=>{if(!this.sessionId)return;const n={requestId:r(32),desktopCode:t,sessionId:h},{headers:i,body:d}=c(n,{apiKey:e,apiSecret:s}),u=await o.deleteSession(d,{headers:i,baseURL:a});return this.sessionId=null,u.data},computer:y};return m}};
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @ctyun/desktop-agent-sdk v0.0.
|
|
2
|
-
import e from"axios";import s from"node:crypto";const t=e.create({baseURL:
|
|
1
|
+
/*! @ctyun/desktop-agent-sdk v0.0.2 | (c) 2026-02-13 zhangjiliang | https://desk.ctyun.cn/html/download/ */
|
|
2
|
+
import e from"axios";import s from"node:crypto";const t=e.create({});[t].forEach(e=>{e.interceptors.request.use(e=>(e=>{const s={baseURL:e.baseURL,url:e.url,payload:e.data},t=Object.keys(e.headers).reduce((s,t)=>(s[t]=e.headers[t],s),{});return s.headers=t,console.log(JSON.stringify(s,null,2)),e})(e)),e.interceptors.response.use(e=>(e=>{const s={url:e.config.url,response:e.data};return console.log(JSON.stringify(s,null,2)),e})(e),e=>(e=>{const s={url:err.config.url,response:e.response.data||{}};return console.error(JSON.stringify(s,null,2)),e})(e))});var o={createSeesion:function(e,s){return t.post("/api/openApi/cdserv/aiUse/createSession",e,{...s})},sendMessage:function(e,s){return t.post("/api/openApi/cdserv/aiUse/sendMessage",e,{...s})},queryJob:function(e,s){return t.post("/api/openApi/cdserv/aiUse/queryJob",e,{...s})},deleteSession:function(e,s){return t.post("/api/openApi/cdserv/aiUse/deleteSession",e,{...s})}};const r=e=>{const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",o=s.randomBytes(e);let r="";for(let e=0;e<o.length;e++)r+=t[o[e]%62];return r.slice(0,e)},a=e=>{const{path:t,body:o,apiKey:a,apiSecret:n}=e;let i={};const c=t.indexOf("?");-1!==c&&(i=(e=>{if(!e)return{};let s={},t=e.split("&");for(let e=0;e<t.length;e++){let o=t[e].split("=");s[o[0]]=o[1]}return s})(t.slice(c+1)));const d={"x-ctg-ecpc-ak":a,"x-ctg-algorithm":"SHA256","x-ctg-timestamp":(new Date).getTime(),"x-ctg-nonStr":r(8)};o&&(d["x-ctg-reqJson"]=(e=>{const t=s.createHash("md5");return t.update(e),t.digest("hex")})(JSON.stringify(o)));const p=Object.assign({},i,d),u=[],l=Object.keys(p);l.sort(),l.forEach(e=>{u.push(`${e}=${p[e]}`)});const h=u.join("&")+n;return d.sign=(e=>{const t=s.createHash("sha256");return t.update(e),t.digest("hex")})(h),d},n=(e,t)=>{const o=s.createCipheriv("aes-256-cbc",t,"0000000000000000");let r=o.update(e,"utf8","base64");return r+=o.final("base64"),r};var i=Object.freeze({__proto__:null,click_mouse:(e,s,t="left",o="down")=>({action:"ClickMouse",params:{PositionX:e,PositionY:s,Button:t,Press:"down"==o,Release:"up"==o}}),drag_mouse:(e,s,t,o)=>({action:"DragMouse",params:{SourceX:e,SourceY:s,TargetX:t,TargetY:o}}),get_cursor_position:()=>({action:"GetCursorPosition"}),move_mouse:(e,s)=>({action:"MoveMouse",params:{PositionX:e,PositionY:s}}),press_key:e=>({action:"PressKey",params:{Key:e}}),press_mouse:(e,s,t="left")=>({action:"PressMouse",params:{PositionX:e,PositionY:s,Button:t}}),release_mouse:(e,s,t="left")=>({action:"ReleaseMouse",params:{PositionX:e,PositionY:s,Button:t}}),screen_shot:()=>({action:"TakeScreenshot"}),scroll:(e,s,t,o)=>({action:"Scroll",params:{PositionX:e,PositionY:s,Direction:t,Amount:o}}),type_text:e=>({action:"TypeText",params:{Text:e}})});const c=(e,s)=>{const{apiKey:t,apiSecret:o,path:r}=s;return{headers:a({path:r||"",body:e,apiKey:t,apiSecret:o}),body:e}};class d{constructor(e={}){this.options=Object.assign({serviceURL:"https://desk.ctyun.cn:8816"},e);const{apiKey:s,apiSecret:t,desktopCode:o,serviceURL:r}=this.options;if(!s||!t)throw new Error("apiKey或apiSecret不能为空");if(!r)throw new Error("serviceURL不能为空");if(!o)throw new Error("desktopCode不能为空")}async createSession(){const{apiKey:e,apiSecret:s,desktopCode:t,serviceURL:a}=this.options,d={requestId:r(32),desktopCode:t},{headers:p,body:u}=c(d,{apiKey:e,apiSecret:s}),l=await o.createSeesion(u,{headers:p,baseURL:a}),h=this.sessionId=l.data.data.sessionId,y=Object.keys(i).reduce((d,p)=>(d[p]=async(...d)=>{if(!this.sessionId)throw new Error("会话已关闭或未创建");const u=i[p](...d),l=r(32),y={requestId:l,desktopCode:t,sessionId:h,message:n(JSON.stringify(u),l)},{headers:m,body:f}=c(y,{apiKey:e,apiSecret:s}),b=await o.sendMessage(f,{headers:m,baseURL:a}),S=()=>{const{jobId:e,jobRollIntervalMs:s,jobRollTimes:t}=b.data.data;return new Promise((o,r)=>{let a=0;const n=async()=>{if(a++,!this.sessionId)return r({code:-1,data:null,msg:"会话已关闭"});if(a>t)return r({code:-1,data:null,msg:"已超时"});const i=(new Date).getTime();try{const t=await g(e),r=(new Date).getTime(),a=r-i>=s?0:s-(r-i);if(0==t.data.code){const{resp:e,respFlag:s}=t.data.data;s?o({code:0,data:e,msg:null}):setTimeout(()=>n(),a)}else setTimeout(()=>n(),a)}catch(e){const t=(new Date).getTime();setTimeout(()=>n(),t-i>=s?0:s-(t-i))}};setTimeout(()=>n(),s)})};if(0==b.data.code){return await S()}return{code:code,data:null,msg:"发送失败"}},d),{}),g=async n=>{if(!this.sessionId)throw new Error("会话已关闭或未创建");const i={requestId:r(32),desktopCode:t,sessionId:h,jobId:n},{headers:d,body:p}=c(i,{apiKey:e,apiSecret:s});return(await o.queryJob(p,{headers:d,baseURL:a})).data},m={sessionId:h,close:async()=>{if(!this.sessionId)return;const n={requestId:r(32),desktopCode:t,sessionId:h},{headers:i,body:d}=c(n,{apiKey:e,apiSecret:s}),p=await o.deleteSession(d,{headers:i,baseURL:a});return this.sessionId=null,p.data},computer:y};return m}}export{d as default};
|