@cloudbase/agent-adapter-adp 0.0.13

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/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # @cloudbase/agent-adapter-adp
2
+
3
+ ## 1.0.1-alpha.6
4
+
5
+ ### Features
6
+
7
+ - Initial release of the ADP (Agent Development Platform) adapter
8
+ - **AdpAgent**: Agent implementation that connects to Tencent Cloud ADP chatbot services
9
+ - **Streaming Support**: Real-time SSE (Server-Sent Events) streaming responses
10
+ - **Workflow Integration**: Support for ADP workflows with tool call events
11
+ - **Custom Variables**: Pass custom parameters to workflows and knowledge base
12
+ - **Flexible Credentials**: Support credentials via environment variables or config
13
+
14
+ ### Configuration
15
+
16
+ - `appKey`: ADP application key (optional if `ADP_APP_KEY` env is set)
17
+ - `secretId`: Tencent Cloud secret ID (optional if `CAPI_SECRET_ID` env is set)
18
+ - `secretKey`: Tencent Cloud secret key (optional if `CAPI_SECRET_KEY` env is set)
19
+ - `historyCount`: Number of history messages to retrieve
20
+ - `request`: Additional request options (model, search, workflow settings)
21
+
22
+ ### Dependencies
23
+
24
+ - @cloudbase/agent-agents@1.0.1-alpha.6
25
+ - @ag-ui/client@0.0.42
26
+ - axios@^1.13.2
27
+ - cos-nodejs-sdk-v5@^2.15.4
28
+ - rxjs@^7.8.1
29
+ - tencentcloud-sdk-nodejs-lke@^4.1.169
30
+ - zod@^3.25.0 || ^4.0.0
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # @cloudbase/agent-adapter-adp
2
+
3
+ Tencent Cloud ADP (Agent Development Platform) adapter for AG-Kit agents. This package provides integration between AG-Kit and Tencent Cloud's LKE (Large Knowledge Engine) service, enabling you to use ADP chatbots with AG-Kit's agent infrastructure.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @cloudbase/agent-agents @cloudbase/agent-adapter-adp
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **AdpAgent**: Agent implementation that connects to Tencent Cloud ADP chatbot services
14
+ - **Streaming Support**: Real-time SSE (Server-Sent Events) streaming responses
15
+ - **Workflow Integration**: Support for ADP workflows with tool call events
16
+ - **Document Parsing**: Built-in document extraction support (PDF, Word, PPT, TXT)
17
+ - **Custom Variables**: Pass custom parameters to workflows and knowledge base
18
+
19
+ ## Environment Variables
20
+
21
+ Configure the following environment variables:
22
+
23
+ ```bash
24
+ ADP_APP_KEY=your-adp-app-key
25
+ CAPI_SECRET_ID=your-tencent-cloud-secret-id
26
+ CAPI_SECRET_KEY=your-tencent-cloud-secret-key
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ### Basic Agent Setup
32
+
33
+ ```typescript
34
+ import { AdpAgent } from "@cloudbase/agent-adapter-adp";
35
+
36
+ // Create the agent
37
+ const agent = new AdpAgent({
38
+ name: "my-adp-agent",
39
+ description: "A Tencent Cloud ADP chatbot agent",
40
+ adpConfig: {
41
+ appKey: process.env.ADP_APP_KEY, // Optional if set in env
42
+ historyCount: 30, // Number of history messages to retrieve
43
+ },
44
+ });
45
+ ```
46
+
47
+ ### With Credentials in Config
48
+
49
+ ```typescript
50
+ import { AdpAgent } from "@cloudbase/agent-adapter-adp";
51
+
52
+ const agent = new AdpAgent({
53
+ name: "my-adp-agent",
54
+ description: "An ADP agent with inline credentials",
55
+ adpConfig: {
56
+ appKey: "your-app-key", // Optional if ADP_APP_KEY env is set
57
+ secretId: "your-secret-id", // Optional if CAPI_SECRET_ID env is set
58
+ secretKey: "your-secret-key", // Optional if CAPI_SECRET_KEY env is set
59
+ },
60
+ });
61
+ ```
62
+
63
+ ### With Custom Request Options
64
+
65
+ For further information, please check the [official documentation](https://cloud.tencent.com/document/product/1759/105561#ba7e0c00-8616-468c-8734-6cc13b4c51af).
66
+
67
+ ```typescript
68
+ import { AdpAgent } from "@cloudbase/agent-adapter-adp";
69
+
70
+ const agent = new AdpAgent({
71
+ name: "my-adp-agent",
72
+ description: "An ADP agent with custom config",
73
+ adpConfig: {
74
+ appKey: "your-app-key",
75
+ request: {
76
+ modelName: "gpt-4", // Specify model
77
+ searchNetwork: "enable", // Enable web search
78
+ workflowStatus: "enable", // Enable workflows
79
+ systemRole: "You are a helpful assistant", // Custom system prompt
80
+ ...otherConfigs,
81
+ },
82
+ },
83
+ });
84
+ ```
85
+
86
+ ### Running the Agent
87
+
88
+ ```typescript
89
+ import { randomUUID } from "crypto";
90
+
91
+ const runId = randomUUID();
92
+ const threadId = randomUUID();
93
+
94
+ const observable = agent.run({
95
+ runId,
96
+ threadId,
97
+ messages: [
98
+ {
99
+ id: randomUUID(),
100
+ role: "user",
101
+ content: "Hello, how can you help me?",
102
+ },
103
+ ],
104
+ forwardedProps: {
105
+ userId: "user-123",
106
+ customVariables: {
107
+ key1: "value1",
108
+ },
109
+ },
110
+ });
111
+
112
+ observable.subscribe({
113
+ next: (event) => console.log(event),
114
+ complete: () => console.log("Done"),
115
+ error: (err) => console.error(err),
116
+ });
117
+ ```
118
+
119
+ ## API Reference
120
+
121
+ ### AdpAgent
122
+
123
+ Agent class that extends `AbstractAgent` and connects to Tencent Cloud ADP services.
124
+
125
+ **Constructor:**
126
+
127
+ ```typescript
128
+ constructor(config: AgentConfig & { adpConfig: AdpConfig })
129
+ ```
130
+
131
+ ### AdpConfig
132
+
133
+ Configuration options for the ADP adapter.
134
+
135
+ ```typescript
136
+ interface AdpConfig {
137
+ appKey?: string; // ADP application key (optional if ADP_APP_KEY env is set)
138
+ secretId?: string; // Tencent Cloud secret ID (optional if CAPI_SECRET_ID env is set)
139
+ secretKey?: string; // Tencent Cloud secret key (optional if CAPI_SECRET_KEY env is set)
140
+ historyCount?: number; // Number of history messages to retrieve
141
+ request?: Partial<AdpChatRequest>; // Additional request options
142
+ }
143
+ ```
144
+
145
+ ### AdpChatRequest Options
146
+
147
+ ```typescript
148
+ interface AdpChatRequest {
149
+ streamingThrottle?: number; // Stream reply frequency control
150
+ customVariables?: Record<string, string>; // Custom parameters for workflows
151
+ systemRole?: string; // Role instructions (prompt)
152
+ searchNetwork?: "" | "enable" | "disable"; // Web search toggle
153
+ modelName?: string; // Specify model name
154
+ stream?: "" | "enable" | "disable"; // Streaming toggle
155
+ workflowStatus?: "" | "enable" | "disable"; // Workflow toggle
156
+ }
157
+ ```
158
+
159
+ ## Supported File Types
160
+
161
+ The adapter supports document extraction for:
162
+
163
+ - Text files (`.txt`)
164
+ - Microsoft Word (`.doc`, `.docx`)
165
+ - PDF documents (`.pdf`)
166
+ - Microsoft PowerPoint (`.ppt`, `.pptx`)
167
+
168
+ ## Requirements
169
+
170
+ - `@cloudbase/agent-agents`: Core agent functionality
171
+ - `@ag-ui/client`: AG-UI client protocol
172
+ - `axios`: HTTP client for API requests
173
+ - `rxjs`: Reactive extensions for JavaScript
174
+ - `tencentcloud-sdk-nodejs-lke`: Tencent Cloud LKE SDK
175
+ - `cos-nodejs-sdk-v5`: Tencent Cloud Object Storage SDK
176
+
177
+ ## Related Resources
178
+
179
+ - [AG-Kit Documentation](https://docs.agkit.dev)
180
+ - [Tencent Cloud ADP Documentation](https://cloud.tencent.com/document/product/1759)
181
+ - [AG-Kit Examples](https://github.com/AgiClass/AG-Kit/tree/main/typescript-sdk/packages/examples)
@@ -0,0 +1,82 @@
1
+ import { AbstractAgent, AgentConfig, RunAgentInput, EventType } from '@ag-ui/client';
2
+ import { Observable } from 'rxjs';
3
+
4
+ /**
5
+ * 文件信息
6
+ */
7
+ interface FileInfo {
8
+ /** 文件名称 */
9
+ fileName: string;
10
+ /** 文件大小(实时文档解析接口返回) */
11
+ fileSize: string;
12
+ /** 文件 URL(实时文档解析接口返回) */
13
+ fileUrl: string;
14
+ /** 文件类型 */
15
+ fileType: string;
16
+ /** 文档 ID(实时文档解析接口返回) */
17
+ docId: string;
18
+ /** 扩展参数 */
19
+ [key: string]: any;
20
+ }
21
+ /**
22
+ * ADP 对话请求参数
23
+ */
24
+ interface AdpChatRequest {
25
+ /** 请求 ID,用于标识一个请求 */
26
+ requestId?: string;
27
+ /** 消息内容 */
28
+ content: string;
29
+ /** 文件信息 */
30
+ fileInfos?: FileInfo[];
31
+ /** 会话 ID,用于标识一个会话 */
32
+ sessionId: string;
33
+ /** 应用密钥 */
34
+ botAppKey: string;
35
+ /** 访客 ID,标识当前接入会话的用户 */
36
+ visitorBizId: string;
37
+ /** 流式回复频率控制,控制应用回包频率 */
38
+ streamingThrottle?: number;
39
+ /** 自定义参数,用于传递参数给工作流或设置知识库检索范围 */
40
+ customVariables?: Record<string, string>;
41
+ /** 角色指令(提示词) */
42
+ systemRole?: string;
43
+ /** 控制回复事件和思考事件中的 content 是否是增量输出 */
44
+ incremental?: boolean;
45
+ /** 是否开启联网搜索:空字符串-跟随配置 / enable / disable */
46
+ searchNetwork?: "" | "enable" | "disable";
47
+ /** 指定模型名称 */
48
+ modelName?: string;
49
+ /** 是否开启流式传输:空字符串-跟随配置 / enable / disable */
50
+ stream?: "" | "enable" | "disable";
51
+ /** 是否开启工作流:空字符串-跟随配置 / enable / disable */
52
+ workflowStatus?: "" | "enable" | "disable";
53
+ /** 扩展参数 */
54
+ [key: string]: any;
55
+ }
56
+ type AdpConfig = {
57
+ request?: Partial<AdpChatRequest>;
58
+ historyCount?: number;
59
+ appKey?: string;
60
+ credential?: {
61
+ secretId?: string;
62
+ secretKey?: string;
63
+ token?: string;
64
+ };
65
+ };
66
+
67
+ declare class AdpAgent extends AbstractAgent {
68
+ private adpConfig;
69
+ private reqAppClient;
70
+ private reqLkeClient;
71
+ constructor(config: AgentConfig & {
72
+ adpConfig: AdpConfig;
73
+ });
74
+ run(input: RunAgentInput): Observable<{
75
+ type: EventType;
76
+ timestamp?: number | undefined;
77
+ rawEvent?: any;
78
+ }>;
79
+ private _run;
80
+ }
81
+
82
+ export { AdpAgent };
@@ -0,0 +1,82 @@
1
+ import { AbstractAgent, AgentConfig, RunAgentInput, EventType } from '@ag-ui/client';
2
+ import { Observable } from 'rxjs';
3
+
4
+ /**
5
+ * 文件信息
6
+ */
7
+ interface FileInfo {
8
+ /** 文件名称 */
9
+ fileName: string;
10
+ /** 文件大小(实时文档解析接口返回) */
11
+ fileSize: string;
12
+ /** 文件 URL(实时文档解析接口返回) */
13
+ fileUrl: string;
14
+ /** 文件类型 */
15
+ fileType: string;
16
+ /** 文档 ID(实时文档解析接口返回) */
17
+ docId: string;
18
+ /** 扩展参数 */
19
+ [key: string]: any;
20
+ }
21
+ /**
22
+ * ADP 对话请求参数
23
+ */
24
+ interface AdpChatRequest {
25
+ /** 请求 ID,用于标识一个请求 */
26
+ requestId?: string;
27
+ /** 消息内容 */
28
+ content: string;
29
+ /** 文件信息 */
30
+ fileInfos?: FileInfo[];
31
+ /** 会话 ID,用于标识一个会话 */
32
+ sessionId: string;
33
+ /** 应用密钥 */
34
+ botAppKey: string;
35
+ /** 访客 ID,标识当前接入会话的用户 */
36
+ visitorBizId: string;
37
+ /** 流式回复频率控制,控制应用回包频率 */
38
+ streamingThrottle?: number;
39
+ /** 自定义参数,用于传递参数给工作流或设置知识库检索范围 */
40
+ customVariables?: Record<string, string>;
41
+ /** 角色指令(提示词) */
42
+ systemRole?: string;
43
+ /** 控制回复事件和思考事件中的 content 是否是增量输出 */
44
+ incremental?: boolean;
45
+ /** 是否开启联网搜索:空字符串-跟随配置 / enable / disable */
46
+ searchNetwork?: "" | "enable" | "disable";
47
+ /** 指定模型名称 */
48
+ modelName?: string;
49
+ /** 是否开启流式传输:空字符串-跟随配置 / enable / disable */
50
+ stream?: "" | "enable" | "disable";
51
+ /** 是否开启工作流:空字符串-跟随配置 / enable / disable */
52
+ workflowStatus?: "" | "enable" | "disable";
53
+ /** 扩展参数 */
54
+ [key: string]: any;
55
+ }
56
+ type AdpConfig = {
57
+ request?: Partial<AdpChatRequest>;
58
+ historyCount?: number;
59
+ appKey?: string;
60
+ credential?: {
61
+ secretId?: string;
62
+ secretKey?: string;
63
+ token?: string;
64
+ };
65
+ };
66
+
67
+ declare class AdpAgent extends AbstractAgent {
68
+ private adpConfig;
69
+ private reqAppClient;
70
+ private reqLkeClient;
71
+ constructor(config: AgentConfig & {
72
+ adpConfig: AdpConfig;
73
+ });
74
+ run(input: RunAgentInput): Observable<{
75
+ type: EventType;
76
+ timestamp?: number | undefined;
77
+ rawEvent?: any;
78
+ }>;
79
+ private _run;
80
+ }
81
+
82
+ export { AdpAgent };
package/dist/index.js ADDED
@@ -0,0 +1,402 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AdpAgent: () => AdpAgent
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/agent.ts
38
+ var import_client = require("@ag-ui/client");
39
+ var import_rxjs = require("rxjs");
40
+ var import_axios = __toESM(require("axios"));
41
+
42
+ // src/utils.ts
43
+ function camelToSnake(str) {
44
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
45
+ }
46
+ function camelToSnakeKeys(obj) {
47
+ if (obj === null || obj === void 0) {
48
+ return obj;
49
+ }
50
+ if (Array.isArray(obj)) {
51
+ return obj.map((item) => camelToSnakeKeys(item));
52
+ }
53
+ if (typeof obj === "object") {
54
+ const result = {};
55
+ for (const [key, value] of Object.entries(obj)) {
56
+ const snakeKey = camelToSnake(key);
57
+ result[snakeKey] = camelToSnakeKeys(value);
58
+ }
59
+ return result;
60
+ }
61
+ return obj;
62
+ }
63
+
64
+ // src/constant.ts
65
+ var MIME_TYPES = {
66
+ "text/plain": "txt",
67
+ "application/msword": "doc",
68
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
69
+ "application/pdf": "pdf",
70
+ "application/vnd.ms-powerpoint": "ppt",
71
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx"
72
+ };
73
+
74
+ // src/agent.ts
75
+ var import_crypto = require("crypto");
76
+ var import_tencentcloud_sdk_nodejs_lke = require("tencentcloud-sdk-nodejs-lke");
77
+ var AdpAgent = class extends import_client.AbstractAgent {
78
+ constructor(config) {
79
+ super(config);
80
+ this.adpConfig = config.adpConfig;
81
+ this.reqAppClient = import_axios.default.create({
82
+ baseURL: "https://wss.lke.cloud.tencent.com"
83
+ });
84
+ const LkeClient = import_tencentcloud_sdk_nodejs_lke.lke.v20231130.Client;
85
+ const credential = this.adpConfig.credential;
86
+ this.reqLkeClient = new LkeClient({
87
+ credential: credential ? credential : {
88
+ secretId: credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
89
+ secretKey: credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
90
+ token: credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
91
+ }
92
+ });
93
+ }
94
+ run(input) {
95
+ return new import_rxjs.Observable((subscriber) => {
96
+ this._run(subscriber, input);
97
+ });
98
+ }
99
+ async _run(subscriber, input) {
100
+ try {
101
+ const { messages, runId, threadId, forwardedProps } = input;
102
+ subscriber.next({
103
+ type: import_client.EventType.RUN_STARTED,
104
+ runId,
105
+ threadId
106
+ });
107
+ if (!this.adpConfig.appKey && !process.env.ADP_APP_KEY) {
108
+ throw new Error(
109
+ "ADP app key is required, check your env variables or config passed with the adapter"
110
+ );
111
+ }
112
+ const { messages: docExtractedMessages, fileInfos } = await extractDocuments(messages, this.adpConfig, this.reqLkeClient);
113
+ const { message, trimmed } = convertAGUIMessagesToAdpMessages(docExtractedMessages);
114
+ if (!message) {
115
+ throw new Error("Message content format error, or empty content");
116
+ }
117
+ if (trimmed > 0) {
118
+ subscriber.next({
119
+ type: import_client.EventType.RAW,
120
+ rawEvent: {
121
+ message: `ADP handles message history itself, so that a total of ${trimmed} messages before and including last assistant message will be trimmed.`,
122
+ type: "warn"
123
+ }
124
+ });
125
+ }
126
+ const requestBody = {
127
+ requestId: runId,
128
+ content: message,
129
+ fileInfos,
130
+ botAppKey: this.adpConfig.appKey || process.env.ADP_APP_KEY,
131
+ sessionId: threadId,
132
+ visitorBizId: forwardedProps?.userId || (0, import_crypto.randomUUID)(),
133
+ incremental: true,
134
+ stream: "enable",
135
+ customVariables: forwardedProps?.customVariables || {},
136
+ ...this.adpConfig.request
137
+ };
138
+ const response = await this.reqAppClient.post(
139
+ "/v1/qbot/chat/sse",
140
+ camelToSnakeKeys(requestBody),
141
+ { responseType: "stream" }
142
+ );
143
+ const sseStream = response.data;
144
+ let buffer = "";
145
+ let interruptRequested = false;
146
+ let thinkingStart = false;
147
+ let thinkingMessageSet = /* @__PURE__ */ new Set();
148
+ for await (const chunk of sseStream) {
149
+ buffer += chunk.toString();
150
+ const parts = buffer.split("\n\n");
151
+ buffer = parts.pop() || "";
152
+ for (const part of parts) {
153
+ if (!part.trim()) continue;
154
+ const event = { data: "", event: "" };
155
+ for (const line of part.split("\n")) {
156
+ if (line.startsWith("data:")) {
157
+ event.data += line.slice(5);
158
+ } else if (line.startsWith("event:")) {
159
+ event.event = line.slice(6);
160
+ }
161
+ }
162
+ if (event.data) {
163
+ let data;
164
+ try {
165
+ data = JSON.parse(event.data);
166
+ } catch (e) {
167
+ throw new Error(`ADP returned invalid data: ${event.data}`);
168
+ }
169
+ switch (data.type) {
170
+ case "reply": {
171
+ if (data.payload.is_from_self) {
172
+ if (data.payload.is_evil) {
173
+ throw new Error("Message filtered by ADP");
174
+ } else {
175
+ continue;
176
+ }
177
+ }
178
+ const messageId = data.payload.record_id;
179
+ const isFinal = data.payload.is_final;
180
+ data.payload.content = data.payload.content.replace(
181
+ /\\n/g,
182
+ "\n\n"
183
+ );
184
+ switch (data.payload.reply_method) {
185
+ case 1 /* LLM_REPLY */: {
186
+ subscriber.next({
187
+ type: import_client.EventType.TEXT_MESSAGE_CHUNK,
188
+ messageId,
189
+ delta: data.payload.content
190
+ });
191
+ break;
192
+ }
193
+ case 16 /* WORKFLOW_REPLY */: {
194
+ subscriber.next({
195
+ type: import_client.EventType.TEXT_MESSAGE_CHUNK,
196
+ messageId,
197
+ delta: data.payload.content
198
+ });
199
+ if (isFinal && data.payload.work_flow && [
200
+ 0 /* Pending */,
201
+ 1 /* Running */
202
+ ].includes(data.payload.work_flow.current_node.Status)) {
203
+ subscriber.next({
204
+ type: import_client.EventType.TOOL_CALL_START,
205
+ toolCallId: data.payload.work_flow.current_node.NodeID,
206
+ toolCallName: `${data.payload.work_flow.workflow_name}-${data.payload.work_flow.current_node.NodeName}`,
207
+ parentMessageId: messageId
208
+ });
209
+ subscriber.next({
210
+ type: import_client.EventType.TOOL_CALL_ARGS,
211
+ toolCallId: data.payload.work_flow.current_node.NodeID,
212
+ delta: data.payload.work_flow.current_node.Input || "{}"
213
+ });
214
+ subscriber.next({
215
+ type: import_client.EventType.TOOL_CALL_END,
216
+ toolCallId: data.payload.work_flow.current_node.NodeID
217
+ });
218
+ interruptRequested = true;
219
+ }
220
+ break;
221
+ }
222
+ case 17 /* WORKFLOW_EXECUTION_END */: {
223
+ subscriber.next({
224
+ type: import_client.EventType.TOOL_CALL_RESULT,
225
+ messageId,
226
+ toolCallId: data.payload.work_flow.current_node.NodeID,
227
+ content: (data.payload.work_flow?.outputs || []).join(
228
+ "\n\n"
229
+ )
230
+ });
231
+ subscriber.next({
232
+ type: import_client.EventType.TEXT_MESSAGE_CHUNK,
233
+ messageId,
234
+ delta: data.payload.content
235
+ });
236
+ break;
237
+ }
238
+ default: {
239
+ subscriber.next({
240
+ type: import_client.EventType.TEXT_MESSAGE_CHUNK,
241
+ messageId,
242
+ delta: data.payload.content
243
+ });
244
+ break;
245
+ }
246
+ }
247
+ break;
248
+ }
249
+ case "thought": {
250
+ const messageId = data.payload.record_id;
251
+ if (!thinkingStart) {
252
+ thinkingStart = true;
253
+ subscriber.next({
254
+ type: import_client.EventType.THINKING_START,
255
+ messageId
256
+ });
257
+ }
258
+ data.payload.procedures.forEach((procedure) => {
259
+ if (!thinkingMessageSet.has(messageId)) {
260
+ thinkingMessageSet.add(messageId);
261
+ subscriber.next({
262
+ type: import_client.EventType.THINKING_TEXT_MESSAGE_START,
263
+ messageId,
264
+ delta: procedure.debugging.content
265
+ });
266
+ } else {
267
+ if (procedure.status === "processing") {
268
+ subscriber.next({
269
+ type: import_client.EventType.THINKING_TEXT_MESSAGE_CONTENT,
270
+ messageId,
271
+ delta: procedure.debugging.content
272
+ });
273
+ } else {
274
+ thinkingMessageSet.delete(messageId);
275
+ subscriber.next({
276
+ type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
277
+ messageId
278
+ });
279
+ }
280
+ }
281
+ });
282
+ const allFinished = data.payload.procedures.every(
283
+ (procedure) => procedure.status !== "processing"
284
+ );
285
+ if (allFinished) {
286
+ thinkingStart = false;
287
+ thinkingMessageSet.clear();
288
+ subscriber.next({
289
+ type: import_client.EventType.THINKING_END,
290
+ messageId
291
+ });
292
+ }
293
+ break;
294
+ }
295
+ case "error": {
296
+ throw new Error(
297
+ `ADP returned error: ${JSON.stringify(data.payload?.error || data.error)}`
298
+ );
299
+ }
300
+ case "token_stat": {
301
+ console.log(JSON.stringify(data, null, 2));
302
+ break;
303
+ }
304
+ case "reference": {
305
+ break;
306
+ }
307
+ default: {
308
+ break;
309
+ }
310
+ }
311
+ }
312
+ }
313
+ }
314
+ if (interruptRequested) {
315
+ subscriber.next({
316
+ type: import_client.EventType.RUN_FINISHED,
317
+ runId,
318
+ threadId,
319
+ outcome: "interrupt",
320
+ interrupt: {}
321
+ });
322
+ } else {
323
+ subscriber.next({
324
+ type: import_client.EventType.RUN_FINISHED,
325
+ threadId,
326
+ runId
327
+ });
328
+ }
329
+ subscriber.complete();
330
+ } catch (e) {
331
+ subscriber.next({
332
+ type: import_client.EventType.RUN_ERROR,
333
+ message: e?.message || JSON.stringify(e)
334
+ });
335
+ subscriber.complete();
336
+ }
337
+ }
338
+ };
339
+ function convertAGUIMessagesToAdpMessages(messages) {
340
+ let result = "";
341
+ let trimmed = messages.length;
342
+ for (const message of messages.reverse()) {
343
+ if (message.role === "assistant") {
344
+ break;
345
+ }
346
+ if (message.role === "user") {
347
+ trimmed--;
348
+ let content = "";
349
+ if (typeof message.content === "string") {
350
+ content = message.content;
351
+ } else {
352
+ content = message.content.reduce((acc, cur) => {
353
+ if (cur.type === "text") {
354
+ return acc + `${cur.text} `;
355
+ } else if (cur.type === "binary") {
356
+ return acc + `![${cur.filename}](${cur.url}) `;
357
+ } else {
358
+ return acc;
359
+ }
360
+ }, "").trim();
361
+ }
362
+ result = `${message.role}: ${content}
363
+ ${result}`;
364
+ } else {
365
+ result = `${message.role}: ${message.content}
366
+ ${result}`;
367
+ }
368
+ }
369
+ return { message: result.trim(), trimmed };
370
+ }
371
+ async function extractDocuments(messages, config, reqLkeClient) {
372
+ const documentFiles = [];
373
+ const newMessages = messages.map((msg) => {
374
+ if (msg.role === "user" && Array.isArray(msg.content)) {
375
+ let newContent = [];
376
+ msg.content.forEach((item) => {
377
+ if (item.type === "text") {
378
+ newContent.push(item);
379
+ } else if (item.type === "binary") {
380
+ if (Object.keys(MIME_TYPES).includes(item.mimeType)) {
381
+ documentFiles.push(item);
382
+ }
383
+ }
384
+ });
385
+ return {
386
+ ...msg,
387
+ content: newContent
388
+ };
389
+ } else return msg;
390
+ });
391
+ const documentAddresses = [];
392
+ const fileInfos = [];
393
+ return {
394
+ messages: newMessages,
395
+ fileInfos
396
+ };
397
+ }
398
+ // Annotate the CommonJS export names for ESM import in node:
399
+ 0 && (module.exports = {
400
+ AdpAgent
401
+ });
402
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/utils.ts","../src/constant.ts"],"sourcesContent":["export * from \"./agent\";\n","import {\n RunAgentInput,\n Message,\n BaseEvent,\n EventType,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n TextMessageChunkEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n AbstractAgent,\n AgentConfig,\n UserMessage,\n BinaryInputContent,\n ThinkingStartEvent,\n ThinkingTextMessageStartEvent,\n ThinkingTextMessageContentEvent,\n ThinkingTextMessageEndEvent,\n ThinkingEndEvent,\n} from \"@ag-ui/client\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport axios, { AxiosInstance } from \"axios\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { MIME_TYPES } from \"./constant\";\nimport {\n AdpConfig,\n AdpChatRequest,\n AdpChunk,\n ReplyMethod,\n CurrentNodeStatus,\n FileInfo,\n} from \"./types\";\nimport { randomUUID } from \"crypto\";\nimport { lke } from \"tencentcloud-sdk-nodejs-lke\";\nimport COS from \"cos-nodejs-sdk-v5\";\n\nexport class AdpAgent extends AbstractAgent {\n private adpConfig: AdpConfig;\n private reqAppClient: AxiosInstance;\n private reqLkeClient: InstanceType<typeof lke.v20231130.Client>;\n\n constructor(config: AgentConfig & { adpConfig: AdpConfig }) {\n super(config);\n this.adpConfig = config.adpConfig;\n this.reqAppClient = axios.create({\n baseURL: \"https://wss.lke.cloud.tencent.com\",\n });\n const LkeClient = lke.v20231130.Client;\n\n const credential = this.adpConfig.credential;\n this.reqLkeClient = new LkeClient({\n credential: credential\n ? credential\n : {\n secretId:\n (credential as Required<AdpConfig[\"credential\"]>)?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n (credential as Required<AdpConfig[\"credential\"]>)?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n (credential as Required<AdpConfig[\"credential\"]>)?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n },\n });\n }\n\n run(input: RunAgentInput) {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: Subscriber<BaseEvent>, input: RunAgentInput) {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n } as RunStartedEvent);\n\n if (!this.adpConfig.appKey && !process.env.ADP_APP_KEY) {\n throw new Error(\n \"ADP app key is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // try {\n // const historyRes = await this.reqLkeClient.GetMsgRecord({\n // SessionId: threadId,\n // Type: 5,\n // Count: this.adpConfig.historyCount || 30,\n // })\n // const histories = historyRes.Records;\n // if (histories) {\n\n // }\n // } catch (e) {\n // throw new Error(`Get history failed: ${e}`);\n // }\n\n const { messages: docExtractedMessages, fileInfos } =\n await extractDocuments(messages, this.adpConfig, this.reqLkeClient);\n const { message, trimmed } =\n convertAGUIMessagesToAdpMessages(docExtractedMessages);\n if (!message) {\n throw new Error(\"Message content format error, or empty content\");\n }\n if (trimmed > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `ADP handles message history itself, so that a total of ${trimmed} messages before and including last assistant message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n const requestBody: AdpChatRequest = {\n requestId: runId,\n content: message,\n fileInfos,\n botAppKey: this.adpConfig.appKey || process.env.ADP_APP_KEY!,\n sessionId: threadId,\n visitorBizId: forwardedProps?.userId || randomUUID(),\n incremental: true,\n stream: \"enable\",\n customVariables: forwardedProps?.customVariables || {},\n ...this.adpConfig.request,\n };\n\n // console.log(camelToSnakeKeys(requestBody));\n\n const response = await this.reqAppClient.post(\n \"/v1/qbot/chat/sse\",\n camelToSnakeKeys(requestBody),\n { responseType: \"stream\" }\n );\n\n const sseStream: ReadableStream<Uint8Array> = response.data;\n let buffer = \"\";\n let interruptRequested = false;\n let thinkingStart = false;\n let thinkingMessageSet = new Set<string>();\n\n for await (const chunk of sseStream) {\n buffer += chunk.toString();\n\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const event = { data: \"\", event: \"\" };\n\n for (const line of part.split(\"\\n\")) {\n if (line.startsWith(\"data:\")) {\n event.data += line.slice(5);\n } else if (line.startsWith(\"event:\")) {\n event.event = line.slice(6);\n }\n }\n\n if (event.data) {\n let data: AdpChunk;\n try {\n data = JSON.parse(event.data);\n } catch (e) {\n throw new Error(`ADP returned invalid data: ${event.data}`);\n }\n\n switch (data.type) {\n case \"reply\": {\n // console.log(JSON.stringify(data, null, 2));\n\n if (data.payload.is_from_self) {\n if (data.payload.is_evil) {\n throw new Error(\"Message filtered by ADP\");\n } else {\n continue;\n }\n }\n const messageId = data.payload.record_id;\n const isFinal = data.payload.is_final;\n data.payload.content = data.payload.content.replace(\n /\\\\n/g,\n \"\\n\\n\"\n );\n\n switch (data.payload.reply_method) {\n case ReplyMethod.LLM_REPLY: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n case ReplyMethod.WORKFLOW_REPLY: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n if (\n isFinal &&\n data.payload.work_flow &&\n [\n CurrentNodeStatus.Pending,\n CurrentNodeStatus.Running,\n ].includes(data.payload.work_flow.current_node.Status)\n ) {\n subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n toolCallName: `${data.payload.work_flow!.workflow_name}-${data.payload.work_flow!.current_node.NodeName}`,\n parentMessageId: messageId,\n } as ToolCallStartEvent);\n subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n delta:\n data.payload.work_flow!.current_node.Input || \"{}\",\n } as ToolCallArgsEvent);\n subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n } as ToolCallEndEvent);\n interruptRequested = true;\n }\n break;\n }\n case ReplyMethod.WORKFLOW_EXECUTION_END: {\n subscriber.next({\n type: EventType.TOOL_CALL_RESULT,\n messageId,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n content: (data.payload.work_flow?.outputs || []).join(\n \"\\n\\n\"\n ),\n } as ToolCallResultEvent);\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n default: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n }\n break;\n }\n case \"thought\": {\n const messageId = data.payload.record_id;\n if (!thinkingStart) {\n thinkingStart = true;\n subscriber.next({\n type: EventType.THINKING_START,\n messageId,\n } as ThinkingStartEvent);\n }\n data.payload.procedures.forEach((procedure) => {\n if (!thinkingMessageSet.has(messageId)) {\n thinkingMessageSet.add(messageId);\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_START,\n messageId,\n delta: procedure.debugging.content,\n } as ThinkingTextMessageStartEvent);\n } else {\n if (procedure.status === \"processing\") {\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n messageId,\n delta: procedure.debugging.content,\n } as ThinkingTextMessageContentEvent);\n } else {\n thinkingMessageSet.delete(messageId);\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_END,\n messageId,\n } as ThinkingTextMessageEndEvent);\n }\n }\n });\n const allFinished = data.payload.procedures.every(\n (procedure) => procedure.status !== \"processing\"\n );\n if (allFinished) {\n thinkingStart = false;\n thinkingMessageSet.clear();\n subscriber.next({\n type: EventType.THINKING_END,\n messageId,\n } as ThinkingEndEvent);\n }\n break;\n }\n case \"error\": {\n throw new Error(\n `ADP returned error: ${JSON.stringify(data.payload?.error || (data as any).error)}`\n );\n }\n case \"token_stat\": {\n console.log(JSON.stringify(data, null, 2));\n break;\n }\n case \"reference\": {\n // TODO: Reference event\n break;\n }\n default: {\n break;\n }\n }\n }\n }\n }\n\n // Necessary?\n if (interruptRequested) {\n subscriber.next({\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n outcome: \"interrupt\",\n interrupt: {},\n } as RunFinishedEvent);\n } else {\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n }\n subscriber.complete();\n } catch (e: any) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: e?.message || JSON.stringify(e),\n } as RunErrorEvent);\n subscriber.complete();\n }\n }\n}\n\nfunction convertAGUIMessagesToAdpMessages(messages: Message[]): {\n message: string;\n trimmed: number;\n} {\n let result = \"\";\n let trimmed = messages.length;\n for (const message of messages.reverse()) {\n if (message.role === \"assistant\") {\n break;\n }\n if (message.role === \"user\") {\n trimmed--;\n let content = \"\";\n if (typeof message.content === \"string\") {\n content = message.content;\n } else {\n content = message.content\n .reduce((acc, cur) => {\n if (cur.type === \"text\") {\n return acc + `${cur.text} `;\n } else if (cur.type === \"binary\") {\n // TODO: Upload to COS\n return acc + `![${cur.filename}](${cur.url}) `;\n } else {\n return acc;\n }\n }, \"\")\n .trim();\n }\n result = `${message.role}: ${content}\\n${result}`;\n } else {\n result = `${message.role}: ${message.content}\\n${result}`;\n }\n }\n return { message: result.trim(), trimmed };\n}\n\nasync function extractDocuments(\n messages: Message[],\n config: AdpConfig,\n reqLkeClient: InstanceType<typeof lke.v20231130.Client>\n) {\n // Document Parse\n const documentFiles: BinaryInputContent[] = [];\n const newMessages = messages.map((msg) => {\n if (msg.role === \"user\" && Array.isArray(msg.content)) {\n let newContent: UserMessage[\"content\"] = [];\n msg.content.forEach((item) => {\n if (item.type === \"text\") {\n newContent.push(item);\n } else if (item.type === \"binary\") {\n if (Object.keys(MIME_TYPES).includes(item.mimeType)) {\n documentFiles.push(item);\n }\n }\n });\n return {\n ...msg,\n content: newContent,\n };\n } else return msg;\n });\n const documentAddresses = [];\n const fileInfos: FileInfo[] = [];\n // if (documentFiles.length) {\n // try {\n // const bizIdRes = await reqLkeClient.DescribeRobotBizIDByAppKey({\n // AppKey: config.appKey || process.env.ADP_APP_KEY!,\n // });\n // const storageCredRes = await reqLkeClient.DescribeStorageCredential({\n // BotBizId: bizIdRes.BotBizId,\n // });\n // const cosCredId = storageCredRes.Credentials?.TmpSecretId;\n // const cosCredKey = storageCredRes.Credentials?.TmpSecretKey;\n // const cosClient = new COS({\n // SecretId: cosCredId,\n // SecretKey: cosCredKey,\n // SessionToken: storageCredRes.Credentials?.SessionToken,\n // });\n // for (const file of documentFiles) {\n // }\n // } catch (e) {}\n // }\n return {\n messages: newMessages,\n fileInfos,\n };\n}\n\nfunction getCosCredentialParams(extName: string) {}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","export const MIME_TYPES = {\n \"text/plain\": \"txt\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/pdf\": \"pdf\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n};\n"],"mappings":"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","names":["axios"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,368 @@
1
+ // src/agent.ts
2
+ import {
3
+ EventType,
4
+ AbstractAgent
5
+ } from "@ag-ui/client";
6
+ import { Observable } from "rxjs";
7
+ import axios from "axios";
8
+
9
+ // src/utils.ts
10
+ function camelToSnake(str) {
11
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
12
+ }
13
+ function camelToSnakeKeys(obj) {
14
+ if (obj === null || obj === void 0) {
15
+ return obj;
16
+ }
17
+ if (Array.isArray(obj)) {
18
+ return obj.map((item) => camelToSnakeKeys(item));
19
+ }
20
+ if (typeof obj === "object") {
21
+ const result = {};
22
+ for (const [key, value] of Object.entries(obj)) {
23
+ const snakeKey = camelToSnake(key);
24
+ result[snakeKey] = camelToSnakeKeys(value);
25
+ }
26
+ return result;
27
+ }
28
+ return obj;
29
+ }
30
+
31
+ // src/constant.ts
32
+ var MIME_TYPES = {
33
+ "text/plain": "txt",
34
+ "application/msword": "doc",
35
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
36
+ "application/pdf": "pdf",
37
+ "application/vnd.ms-powerpoint": "ppt",
38
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx"
39
+ };
40
+
41
+ // src/agent.ts
42
+ import { randomUUID } from "crypto";
43
+ import { lke } from "tencentcloud-sdk-nodejs-lke";
44
+ var AdpAgent = class extends AbstractAgent {
45
+ constructor(config) {
46
+ super(config);
47
+ this.adpConfig = config.adpConfig;
48
+ this.reqAppClient = axios.create({
49
+ baseURL: "https://wss.lke.cloud.tencent.com"
50
+ });
51
+ const LkeClient = lke.v20231130.Client;
52
+ const credential = this.adpConfig.credential;
53
+ this.reqLkeClient = new LkeClient({
54
+ credential: credential ? credential : {
55
+ secretId: credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
56
+ secretKey: credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
57
+ token: credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
58
+ }
59
+ });
60
+ }
61
+ run(input) {
62
+ return new Observable((subscriber) => {
63
+ this._run(subscriber, input);
64
+ });
65
+ }
66
+ async _run(subscriber, input) {
67
+ try {
68
+ const { messages, runId, threadId, forwardedProps } = input;
69
+ subscriber.next({
70
+ type: EventType.RUN_STARTED,
71
+ runId,
72
+ threadId
73
+ });
74
+ if (!this.adpConfig.appKey && !process.env.ADP_APP_KEY) {
75
+ throw new Error(
76
+ "ADP app key is required, check your env variables or config passed with the adapter"
77
+ );
78
+ }
79
+ const { messages: docExtractedMessages, fileInfos } = await extractDocuments(messages, this.adpConfig, this.reqLkeClient);
80
+ const { message, trimmed } = convertAGUIMessagesToAdpMessages(docExtractedMessages);
81
+ if (!message) {
82
+ throw new Error("Message content format error, or empty content");
83
+ }
84
+ if (trimmed > 0) {
85
+ subscriber.next({
86
+ type: EventType.RAW,
87
+ rawEvent: {
88
+ message: `ADP handles message history itself, so that a total of ${trimmed} messages before and including last assistant message will be trimmed.`,
89
+ type: "warn"
90
+ }
91
+ });
92
+ }
93
+ const requestBody = {
94
+ requestId: runId,
95
+ content: message,
96
+ fileInfos,
97
+ botAppKey: this.adpConfig.appKey || process.env.ADP_APP_KEY,
98
+ sessionId: threadId,
99
+ visitorBizId: forwardedProps?.userId || randomUUID(),
100
+ incremental: true,
101
+ stream: "enable",
102
+ customVariables: forwardedProps?.customVariables || {},
103
+ ...this.adpConfig.request
104
+ };
105
+ const response = await this.reqAppClient.post(
106
+ "/v1/qbot/chat/sse",
107
+ camelToSnakeKeys(requestBody),
108
+ { responseType: "stream" }
109
+ );
110
+ const sseStream = response.data;
111
+ let buffer = "";
112
+ let interruptRequested = false;
113
+ let thinkingStart = false;
114
+ let thinkingMessageSet = /* @__PURE__ */ new Set();
115
+ for await (const chunk of sseStream) {
116
+ buffer += chunk.toString();
117
+ const parts = buffer.split("\n\n");
118
+ buffer = parts.pop() || "";
119
+ for (const part of parts) {
120
+ if (!part.trim()) continue;
121
+ const event = { data: "", event: "" };
122
+ for (const line of part.split("\n")) {
123
+ if (line.startsWith("data:")) {
124
+ event.data += line.slice(5);
125
+ } else if (line.startsWith("event:")) {
126
+ event.event = line.slice(6);
127
+ }
128
+ }
129
+ if (event.data) {
130
+ let data;
131
+ try {
132
+ data = JSON.parse(event.data);
133
+ } catch (e) {
134
+ throw new Error(`ADP returned invalid data: ${event.data}`);
135
+ }
136
+ switch (data.type) {
137
+ case "reply": {
138
+ if (data.payload.is_from_self) {
139
+ if (data.payload.is_evil) {
140
+ throw new Error("Message filtered by ADP");
141
+ } else {
142
+ continue;
143
+ }
144
+ }
145
+ const messageId = data.payload.record_id;
146
+ const isFinal = data.payload.is_final;
147
+ data.payload.content = data.payload.content.replace(
148
+ /\\n/g,
149
+ "\n\n"
150
+ );
151
+ switch (data.payload.reply_method) {
152
+ case 1 /* LLM_REPLY */: {
153
+ subscriber.next({
154
+ type: EventType.TEXT_MESSAGE_CHUNK,
155
+ messageId,
156
+ delta: data.payload.content
157
+ });
158
+ break;
159
+ }
160
+ case 16 /* WORKFLOW_REPLY */: {
161
+ subscriber.next({
162
+ type: EventType.TEXT_MESSAGE_CHUNK,
163
+ messageId,
164
+ delta: data.payload.content
165
+ });
166
+ if (isFinal && data.payload.work_flow && [
167
+ 0 /* Pending */,
168
+ 1 /* Running */
169
+ ].includes(data.payload.work_flow.current_node.Status)) {
170
+ subscriber.next({
171
+ type: EventType.TOOL_CALL_START,
172
+ toolCallId: data.payload.work_flow.current_node.NodeID,
173
+ toolCallName: `${data.payload.work_flow.workflow_name}-${data.payload.work_flow.current_node.NodeName}`,
174
+ parentMessageId: messageId
175
+ });
176
+ subscriber.next({
177
+ type: EventType.TOOL_CALL_ARGS,
178
+ toolCallId: data.payload.work_flow.current_node.NodeID,
179
+ delta: data.payload.work_flow.current_node.Input || "{}"
180
+ });
181
+ subscriber.next({
182
+ type: EventType.TOOL_CALL_END,
183
+ toolCallId: data.payload.work_flow.current_node.NodeID
184
+ });
185
+ interruptRequested = true;
186
+ }
187
+ break;
188
+ }
189
+ case 17 /* WORKFLOW_EXECUTION_END */: {
190
+ subscriber.next({
191
+ type: EventType.TOOL_CALL_RESULT,
192
+ messageId,
193
+ toolCallId: data.payload.work_flow.current_node.NodeID,
194
+ content: (data.payload.work_flow?.outputs || []).join(
195
+ "\n\n"
196
+ )
197
+ });
198
+ subscriber.next({
199
+ type: EventType.TEXT_MESSAGE_CHUNK,
200
+ messageId,
201
+ delta: data.payload.content
202
+ });
203
+ break;
204
+ }
205
+ default: {
206
+ subscriber.next({
207
+ type: EventType.TEXT_MESSAGE_CHUNK,
208
+ messageId,
209
+ delta: data.payload.content
210
+ });
211
+ break;
212
+ }
213
+ }
214
+ break;
215
+ }
216
+ case "thought": {
217
+ const messageId = data.payload.record_id;
218
+ if (!thinkingStart) {
219
+ thinkingStart = true;
220
+ subscriber.next({
221
+ type: EventType.THINKING_START,
222
+ messageId
223
+ });
224
+ }
225
+ data.payload.procedures.forEach((procedure) => {
226
+ if (!thinkingMessageSet.has(messageId)) {
227
+ thinkingMessageSet.add(messageId);
228
+ subscriber.next({
229
+ type: EventType.THINKING_TEXT_MESSAGE_START,
230
+ messageId,
231
+ delta: procedure.debugging.content
232
+ });
233
+ } else {
234
+ if (procedure.status === "processing") {
235
+ subscriber.next({
236
+ type: EventType.THINKING_TEXT_MESSAGE_CONTENT,
237
+ messageId,
238
+ delta: procedure.debugging.content
239
+ });
240
+ } else {
241
+ thinkingMessageSet.delete(messageId);
242
+ subscriber.next({
243
+ type: EventType.THINKING_TEXT_MESSAGE_END,
244
+ messageId
245
+ });
246
+ }
247
+ }
248
+ });
249
+ const allFinished = data.payload.procedures.every(
250
+ (procedure) => procedure.status !== "processing"
251
+ );
252
+ if (allFinished) {
253
+ thinkingStart = false;
254
+ thinkingMessageSet.clear();
255
+ subscriber.next({
256
+ type: EventType.THINKING_END,
257
+ messageId
258
+ });
259
+ }
260
+ break;
261
+ }
262
+ case "error": {
263
+ throw new Error(
264
+ `ADP returned error: ${JSON.stringify(data.payload?.error || data.error)}`
265
+ );
266
+ }
267
+ case "token_stat": {
268
+ console.log(JSON.stringify(data, null, 2));
269
+ break;
270
+ }
271
+ case "reference": {
272
+ break;
273
+ }
274
+ default: {
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ if (interruptRequested) {
282
+ subscriber.next({
283
+ type: EventType.RUN_FINISHED,
284
+ runId,
285
+ threadId,
286
+ outcome: "interrupt",
287
+ interrupt: {}
288
+ });
289
+ } else {
290
+ subscriber.next({
291
+ type: EventType.RUN_FINISHED,
292
+ threadId,
293
+ runId
294
+ });
295
+ }
296
+ subscriber.complete();
297
+ } catch (e) {
298
+ subscriber.next({
299
+ type: EventType.RUN_ERROR,
300
+ message: e?.message || JSON.stringify(e)
301
+ });
302
+ subscriber.complete();
303
+ }
304
+ }
305
+ };
306
+ function convertAGUIMessagesToAdpMessages(messages) {
307
+ let result = "";
308
+ let trimmed = messages.length;
309
+ for (const message of messages.reverse()) {
310
+ if (message.role === "assistant") {
311
+ break;
312
+ }
313
+ if (message.role === "user") {
314
+ trimmed--;
315
+ let content = "";
316
+ if (typeof message.content === "string") {
317
+ content = message.content;
318
+ } else {
319
+ content = message.content.reduce((acc, cur) => {
320
+ if (cur.type === "text") {
321
+ return acc + `${cur.text} `;
322
+ } else if (cur.type === "binary") {
323
+ return acc + `![${cur.filename}](${cur.url}) `;
324
+ } else {
325
+ return acc;
326
+ }
327
+ }, "").trim();
328
+ }
329
+ result = `${message.role}: ${content}
330
+ ${result}`;
331
+ } else {
332
+ result = `${message.role}: ${message.content}
333
+ ${result}`;
334
+ }
335
+ }
336
+ return { message: result.trim(), trimmed };
337
+ }
338
+ async function extractDocuments(messages, config, reqLkeClient) {
339
+ const documentFiles = [];
340
+ const newMessages = messages.map((msg) => {
341
+ if (msg.role === "user" && Array.isArray(msg.content)) {
342
+ let newContent = [];
343
+ msg.content.forEach((item) => {
344
+ if (item.type === "text") {
345
+ newContent.push(item);
346
+ } else if (item.type === "binary") {
347
+ if (Object.keys(MIME_TYPES).includes(item.mimeType)) {
348
+ documentFiles.push(item);
349
+ }
350
+ }
351
+ });
352
+ return {
353
+ ...msg,
354
+ content: newContent
355
+ };
356
+ } else return msg;
357
+ });
358
+ const documentAddresses = [];
359
+ const fileInfos = [];
360
+ return {
361
+ messages: newMessages,
362
+ fileInfos
363
+ };
364
+ }
365
+ export {
366
+ AdpAgent
367
+ };
368
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agent.ts","../src/utils.ts","../src/constant.ts"],"sourcesContent":["import {\n RunAgentInput,\n Message,\n BaseEvent,\n EventType,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n TextMessageChunkEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n AbstractAgent,\n AgentConfig,\n UserMessage,\n BinaryInputContent,\n ThinkingStartEvent,\n ThinkingTextMessageStartEvent,\n ThinkingTextMessageContentEvent,\n ThinkingTextMessageEndEvent,\n ThinkingEndEvent,\n} from \"@ag-ui/client\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport axios, { AxiosInstance } from \"axios\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { MIME_TYPES } from \"./constant\";\nimport {\n AdpConfig,\n AdpChatRequest,\n AdpChunk,\n ReplyMethod,\n CurrentNodeStatus,\n FileInfo,\n} from \"./types\";\nimport { randomUUID } from \"crypto\";\nimport { lke } from \"tencentcloud-sdk-nodejs-lke\";\nimport COS from \"cos-nodejs-sdk-v5\";\n\nexport class AdpAgent extends AbstractAgent {\n private adpConfig: AdpConfig;\n private reqAppClient: AxiosInstance;\n private reqLkeClient: InstanceType<typeof lke.v20231130.Client>;\n\n constructor(config: AgentConfig & { adpConfig: AdpConfig }) {\n super(config);\n this.adpConfig = config.adpConfig;\n this.reqAppClient = axios.create({\n baseURL: \"https://wss.lke.cloud.tencent.com\",\n });\n const LkeClient = lke.v20231130.Client;\n\n const credential = this.adpConfig.credential;\n this.reqLkeClient = new LkeClient({\n credential: credential\n ? credential\n : {\n secretId:\n (credential as Required<AdpConfig[\"credential\"]>)?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n (credential as Required<AdpConfig[\"credential\"]>)?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n (credential as Required<AdpConfig[\"credential\"]>)?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n },\n });\n }\n\n run(input: RunAgentInput) {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: Subscriber<BaseEvent>, input: RunAgentInput) {\n try {\n const { messages, runId, threadId, forwardedProps } = input;\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n } as RunStartedEvent);\n\n if (!this.adpConfig.appKey && !process.env.ADP_APP_KEY) {\n throw new Error(\n \"ADP app key is required, check your env variables or config passed with the adapter\"\n );\n }\n\n // try {\n // const historyRes = await this.reqLkeClient.GetMsgRecord({\n // SessionId: threadId,\n // Type: 5,\n // Count: this.adpConfig.historyCount || 30,\n // })\n // const histories = historyRes.Records;\n // if (histories) {\n\n // }\n // } catch (e) {\n // throw new Error(`Get history failed: ${e}`);\n // }\n\n const { messages: docExtractedMessages, fileInfos } =\n await extractDocuments(messages, this.adpConfig, this.reqLkeClient);\n const { message, trimmed } =\n convertAGUIMessagesToAdpMessages(docExtractedMessages);\n if (!message) {\n throw new Error(\"Message content format error, or empty content\");\n }\n if (trimmed > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `ADP handles message history itself, so that a total of ${trimmed} messages before and including last assistant message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n const requestBody: AdpChatRequest = {\n requestId: runId,\n content: message,\n fileInfos,\n botAppKey: this.adpConfig.appKey || process.env.ADP_APP_KEY!,\n sessionId: threadId,\n visitorBizId: forwardedProps?.userId || randomUUID(),\n incremental: true,\n stream: \"enable\",\n customVariables: forwardedProps?.customVariables || {},\n ...this.adpConfig.request,\n };\n\n // console.log(camelToSnakeKeys(requestBody));\n\n const response = await this.reqAppClient.post(\n \"/v1/qbot/chat/sse\",\n camelToSnakeKeys(requestBody),\n { responseType: \"stream\" }\n );\n\n const sseStream: ReadableStream<Uint8Array> = response.data;\n let buffer = \"\";\n let interruptRequested = false;\n let thinkingStart = false;\n let thinkingMessageSet = new Set<string>();\n\n for await (const chunk of sseStream) {\n buffer += chunk.toString();\n\n const parts = buffer.split(\"\\n\\n\");\n buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const event = { data: \"\", event: \"\" };\n\n for (const line of part.split(\"\\n\")) {\n if (line.startsWith(\"data:\")) {\n event.data += line.slice(5);\n } else if (line.startsWith(\"event:\")) {\n event.event = line.slice(6);\n }\n }\n\n if (event.data) {\n let data: AdpChunk;\n try {\n data = JSON.parse(event.data);\n } catch (e) {\n throw new Error(`ADP returned invalid data: ${event.data}`);\n }\n\n switch (data.type) {\n case \"reply\": {\n // console.log(JSON.stringify(data, null, 2));\n\n if (data.payload.is_from_self) {\n if (data.payload.is_evil) {\n throw new Error(\"Message filtered by ADP\");\n } else {\n continue;\n }\n }\n const messageId = data.payload.record_id;\n const isFinal = data.payload.is_final;\n data.payload.content = data.payload.content.replace(\n /\\\\n/g,\n \"\\n\\n\"\n );\n\n switch (data.payload.reply_method) {\n case ReplyMethod.LLM_REPLY: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n case ReplyMethod.WORKFLOW_REPLY: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n if (\n isFinal &&\n data.payload.work_flow &&\n [\n CurrentNodeStatus.Pending,\n CurrentNodeStatus.Running,\n ].includes(data.payload.work_flow.current_node.Status)\n ) {\n subscriber.next({\n type: EventType.TOOL_CALL_START,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n toolCallName: `${data.payload.work_flow!.workflow_name}-${data.payload.work_flow!.current_node.NodeName}`,\n parentMessageId: messageId,\n } as ToolCallStartEvent);\n subscriber.next({\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n delta:\n data.payload.work_flow!.current_node.Input || \"{}\",\n } as ToolCallArgsEvent);\n subscriber.next({\n type: EventType.TOOL_CALL_END,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n } as ToolCallEndEvent);\n interruptRequested = true;\n }\n break;\n }\n case ReplyMethod.WORKFLOW_EXECUTION_END: {\n subscriber.next({\n type: EventType.TOOL_CALL_RESULT,\n messageId,\n toolCallId: data.payload.work_flow!.current_node.NodeID,\n content: (data.payload.work_flow?.outputs || []).join(\n \"\\n\\n\"\n ),\n } as ToolCallResultEvent);\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n default: {\n subscriber.next({\n type: EventType.TEXT_MESSAGE_CHUNK,\n messageId,\n delta: data.payload.content,\n } as TextMessageChunkEvent);\n break;\n }\n }\n break;\n }\n case \"thought\": {\n const messageId = data.payload.record_id;\n if (!thinkingStart) {\n thinkingStart = true;\n subscriber.next({\n type: EventType.THINKING_START,\n messageId,\n } as ThinkingStartEvent);\n }\n data.payload.procedures.forEach((procedure) => {\n if (!thinkingMessageSet.has(messageId)) {\n thinkingMessageSet.add(messageId);\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_START,\n messageId,\n delta: procedure.debugging.content,\n } as ThinkingTextMessageStartEvent);\n } else {\n if (procedure.status === \"processing\") {\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n messageId,\n delta: procedure.debugging.content,\n } as ThinkingTextMessageContentEvent);\n } else {\n thinkingMessageSet.delete(messageId);\n subscriber.next({\n type: EventType.THINKING_TEXT_MESSAGE_END,\n messageId,\n } as ThinkingTextMessageEndEvent);\n }\n }\n });\n const allFinished = data.payload.procedures.every(\n (procedure) => procedure.status !== \"processing\"\n );\n if (allFinished) {\n thinkingStart = false;\n thinkingMessageSet.clear();\n subscriber.next({\n type: EventType.THINKING_END,\n messageId,\n } as ThinkingEndEvent);\n }\n break;\n }\n case \"error\": {\n throw new Error(\n `ADP returned error: ${JSON.stringify(data.payload?.error || (data as any).error)}`\n );\n }\n case \"token_stat\": {\n console.log(JSON.stringify(data, null, 2));\n break;\n }\n case \"reference\": {\n // TODO: Reference event\n break;\n }\n default: {\n break;\n }\n }\n }\n }\n }\n\n // Necessary?\n if (interruptRequested) {\n subscriber.next({\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n outcome: \"interrupt\",\n interrupt: {},\n } as RunFinishedEvent);\n } else {\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n }\n subscriber.complete();\n } catch (e: any) {\n subscriber.next({\n type: EventType.RUN_ERROR,\n message: e?.message || JSON.stringify(e),\n } as RunErrorEvent);\n subscriber.complete();\n }\n }\n}\n\nfunction convertAGUIMessagesToAdpMessages(messages: Message[]): {\n message: string;\n trimmed: number;\n} {\n let result = \"\";\n let trimmed = messages.length;\n for (const message of messages.reverse()) {\n if (message.role === \"assistant\") {\n break;\n }\n if (message.role === \"user\") {\n trimmed--;\n let content = \"\";\n if (typeof message.content === \"string\") {\n content = message.content;\n } else {\n content = message.content\n .reduce((acc, cur) => {\n if (cur.type === \"text\") {\n return acc + `${cur.text} `;\n } else if (cur.type === \"binary\") {\n // TODO: Upload to COS\n return acc + `![${cur.filename}](${cur.url}) `;\n } else {\n return acc;\n }\n }, \"\")\n .trim();\n }\n result = `${message.role}: ${content}\\n${result}`;\n } else {\n result = `${message.role}: ${message.content}\\n${result}`;\n }\n }\n return { message: result.trim(), trimmed };\n}\n\nasync function extractDocuments(\n messages: Message[],\n config: AdpConfig,\n reqLkeClient: InstanceType<typeof lke.v20231130.Client>\n) {\n // Document Parse\n const documentFiles: BinaryInputContent[] = [];\n const newMessages = messages.map((msg) => {\n if (msg.role === \"user\" && Array.isArray(msg.content)) {\n let newContent: UserMessage[\"content\"] = [];\n msg.content.forEach((item) => {\n if (item.type === \"text\") {\n newContent.push(item);\n } else if (item.type === \"binary\") {\n if (Object.keys(MIME_TYPES).includes(item.mimeType)) {\n documentFiles.push(item);\n }\n }\n });\n return {\n ...msg,\n content: newContent,\n };\n } else return msg;\n });\n const documentAddresses = [];\n const fileInfos: FileInfo[] = [];\n // if (documentFiles.length) {\n // try {\n // const bizIdRes = await reqLkeClient.DescribeRobotBizIDByAppKey({\n // AppKey: config.appKey || process.env.ADP_APP_KEY!,\n // });\n // const storageCredRes = await reqLkeClient.DescribeStorageCredential({\n // BotBizId: bizIdRes.BotBizId,\n // });\n // const cosCredId = storageCredRes.Credentials?.TmpSecretId;\n // const cosCredKey = storageCredRes.Credentials?.TmpSecretKey;\n // const cosClient = new COS({\n // SecretId: cosCredId,\n // SecretKey: cosCredKey,\n // SessionToken: storageCredRes.Credentials?.SessionToken,\n // });\n // for (const file of documentFiles) {\n // }\n // } catch (e) {}\n // }\n return {\n messages: newMessages,\n fileInfos,\n };\n}\n\nfunction getCosCredentialParams(extName: string) {}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n","export const MIME_TYPES = {\n \"text/plain\": \"txt\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/pdf\": \"pdf\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n};\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@cloudbase/agent-adapter-adp",
3
+ "version": "0.0.13",
4
+ "description": "ADP adapter for AG-Kit agents",
5
+ "files": [
6
+ "dist/",
7
+ "README.md",
8
+ "CHANGELOG.md"
9
+ ],
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.mjs",
15
+ "types": "dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "import": {
19
+ "types": "./dist/index.d.mts",
20
+ "default": "./dist/index.mjs"
21
+ },
22
+ "require": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
26
+ }
27
+ },
28
+ "keywords": [
29
+ "ag-kit",
30
+ "adp",
31
+ "adapter",
32
+ "agent"
33
+ ],
34
+ "author": "",
35
+ "license": "ISC",
36
+ "devDependencies": {
37
+ "@types/node": "^20.0.0",
38
+ "tsup": "^8.5.0",
39
+ "typescript": "^5.0.0"
40
+ },
41
+ "dependencies": {
42
+ "@cloudbase/agent-agents": "0.0.12",
43
+ "@ag-ui/client": "0.0.42",
44
+ "axios": "^1.13.2",
45
+ "cos-nodejs-sdk-v5": "^2.15.4",
46
+ "rxjs": "^7.8.1",
47
+ "tencentcloud-sdk-nodejs-lke": "^4.1.169",
48
+ "zod": "^3.25.0 || ^4.0.0"
49
+ },
50
+ "peerDependencies": {
51
+ "@cloudbase/agent-agents": "0.0.12",
52
+ "zod": "^3.25.0 || ^4.0.0"
53
+ },
54
+ "scripts": {
55
+ "test": "echo \"Error: no test specified\" && exit 1",
56
+ "build": "tsup --config tsup.config.ts"
57
+ }
58
+ }