@codebolt/codeboltjs 1.1.89 → 1.1.91

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.
@@ -15,7 +15,7 @@ declare class cbws {
15
15
  * when the WebSocket connection is successfully opened.
16
16
  * @returns {Promise<WebSocket>} A promise that resolves with the WebSocket instance.
17
17
  */
18
- private initializeWebSocket;
18
+ initializeWebSocket(): Promise<WebSocket>;
19
19
  /**
20
20
  * Getter for the WebSocket instance. Throws an error if the WebSocket is not open.
21
21
  * @returns {WebSocket} The WebSocket instance.
@@ -14,14 +14,11 @@ class cbws {
14
14
  * Constructs a new cbws instance and initializes the WebSocket connection.
15
15
  */
16
16
  constructor() {
17
- const uniqueConnectionId = this.getUniqueConnectionId();
18
- const initialMessage = this.getInitialMessage();
19
- const agentIdParam = process.env.agentId ? `&agentId=${process.env.agentId}` : '';
20
- const parentIdParam = process.env.parentId ? `&parentId=${process.env.parentId}` : '';
21
- this.websocket = new ws_1.default(`ws://localhost:${process.env.SOCKET_PORT}/codebolt?id=${uniqueConnectionId}${agentIdParam}${parentIdParam}${process.env.Is_Dev ? '&dev=true' : ''}`);
22
- this.initializeWebSocket(initialMessage).catch(error => {
23
- console.error("WebSocket connection failed:", error);
24
- });
17
+ // this.websocket=undefined;
18
+ // this.websocket = new WebSocket(`ws://localhost:${process.env.SOCKET_PORT}/codebolt?id=${uniqueConnectionId}${agentIdParam}${parentIdParam}${process.env.Is_Dev ? '&dev=true' : ''}`);
19
+ // this.initializeWebSocket(initialMessage).catch(error => {
20
+ // console.error("WebSocket connection failed:", error);
21
+ // });
25
22
  }
26
23
  getUniqueConnectionId() {
27
24
  try {
@@ -41,7 +38,7 @@ class cbws {
41
38
  return data.initial_message;
42
39
  }
43
40
  catch (e) {
44
- console.error('Unable to locate codeboltagent.yaml file.');
41
+ // console.error('Unable to locate codeboltagent.yaml file.');
45
42
  return '';
46
43
  }
47
44
  }
@@ -50,7 +47,12 @@ class cbws {
50
47
  * when the WebSocket connection is successfully opened.
51
48
  * @returns {Promise<WebSocket>} A promise that resolves with the WebSocket instance.
52
49
  */
53
- async initializeWebSocket(initialMessage) {
50
+ async initializeWebSocket() {
51
+ const uniqueConnectionId = this.getUniqueConnectionId();
52
+ const initialMessage = this.getInitialMessage();
53
+ const agentIdParam = process.env.agentId ? `&agentId=${process.env.agentId}` : '';
54
+ const parentIdParam = process.env.parentId ? `&parentId=${process.env.parentId}` : '';
55
+ this.websocket = new ws_1.default(`ws://localhost:${process.env.SOCKET_PORT}/codebolt?id=${uniqueConnectionId}${agentIdParam}${parentIdParam}${process.env.Is_Dev ? '&dev=true' : ''}`);
54
56
  return new Promise((resolve, reject) => {
55
57
  this.websocket.on('error', (error) => {
56
58
  console.log('WebSocket error:', error);
@@ -78,7 +80,7 @@ class cbws {
78
80
  * @throws {Error} If the WebSocket is not open.
79
81
  */
80
82
  get getWebsocket() {
81
- if (!this.websocket.OPEN) {
83
+ if (this.websocket && !this.websocket.OPEN) {
82
84
  throw new Error('WebSocket is not open');
83
85
  }
84
86
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebolt/codeboltjs",
3
- "version": "1.1.89",
3
+ "version": "1.1.91",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "author": "",
@@ -20,28 +20,52 @@
20
20
  "homepage": "https://codeboltai.github.io",
21
21
  "dependencies": {
22
22
  "@codebolt/types": "^1.0.10",
23
+ "@modelcontextprotocol/sdk": "^1.4.1",
24
+ "execa": "^9.5.2",
25
+ "file-type": "^19.6.0",
26
+ "fuse.js": "^7.0.0",
23
27
  "js-yaml": "^4.1.0",
28
+ "load-esm": "^1.0.1",
29
+ "mcp-proxy": "^2.4.0",
30
+ "strict-event-emitter-types": "^2.0.0",
31
+ "timers": "^0.1.1",
24
32
  "tree-sitter": "^0.21.1",
25
33
  "tree-sitter-javascript": "^0.23.1",
26
34
  "tree-sitter-typescript": "^0.23.2",
27
35
  "typedoc-plugin-missing-exports": "^2.2.0",
28
- "ws": "^8.17.0"
36
+ "uri-templates": "^0.2.0",
37
+ "ws": "^8.17.0",
38
+ "yargs": "^17.7.2",
39
+ "zod": "^3.24.1",
40
+ "zod-to-json-schema": "^3.24.1"
29
41
  },
30
42
  "devDependencies": {
31
43
  "@types/events": "^3.0.3",
32
44
  "@types/js-yaml": "^4.0.9",
33
45
  "@types/node": "^20.14.2",
46
+ "@types/uri-templates": "^0.1.34",
34
47
  "@types/ws": "^8.5.10",
35
48
  "jest": "^29.7.0",
36
49
  "jest-serial-runner": "^1.2.1",
37
50
  "ts-loader": "^9.5.1",
38
51
  "typedoc": "^0.25.13",
39
- "typedoc-plugin-markdown": "^4.0.1",
52
+ "typedoc-plugin-markdown": "^3.15.0",
53
+ "typedoc-plugin-missing-exports": "^2.2.0",
40
54
  "typescript": "^5.4.5",
41
55
  "webpack": "^5.91.0",
42
56
  "webpack-cli": "^5.1.4"
43
57
  },
44
58
  "jest": {
45
59
  "testTimeout": 50000
60
+ },
61
+ "exports": {
62
+ ".": {
63
+ "types": "./index.d.ts",
64
+ "default": "./index.js"
65
+ },
66
+ "./utils": {
67
+ "types": "./utils.d.ts",
68
+ "default": "./utils.js"
69
+ }
46
70
  }
47
- }
71
+ }
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ import cbagent from './modules/agent';
28
28
 
29
29
 
30
30
 
31
+
31
32
  /**
32
33
  * @class Codebolt
33
34
  * @description This class provides a unified interface to interact with various modules.
@@ -39,8 +40,9 @@ class Codebolt { // Extend EventEmitter
39
40
  * @description Initializes the websocket connection.
40
41
  */
41
42
  constructor() {
42
-
43
+ cbws.initializeWebSocket()
43
44
  this.websocket = cbws.getWebsocket;
45
+
44
46
  }
45
47
 
46
48
  /**
@@ -96,8 +98,10 @@ class Codebolt { // Extend EventEmitter
96
98
  chatSummary=chatSummary;
97
99
  MCP = codeboltMCP;
98
100
  AGENT = cbagent;
101
+
99
102
  }
100
103
 
101
104
  export default new Codebolt();
102
105
 
103
- // module.exports = new Codebolt();
106
+
107
+
@@ -1,22 +1,48 @@
1
1
  import { GetAgentStateResponse } from '@codebolt/types';
2
2
  import cbws from './websocket';
3
3
 
4
+
5
+ export enum AgentLocation {
6
+ ALL = 'all',
7
+ LOCAL_ONLY = 'local_only',
8
+ REMOTE_ONLY = 'remote_only',
9
+ }
10
+
11
+
12
+ export enum Agents {
13
+ LOCAL = 'local',
14
+ ALL = 'all',
15
+ DOWNLOADED = 'downloaded',
16
+ }
17
+
18
+ export enum FilterUsing {
19
+ USE_AI = 'use_ai',
20
+ USE_VECTOR_DB = 'use_vector_db',
21
+ USE_BOTH = 'use_both',
22
+ }
23
+
24
+
25
+
4
26
  const codeboltAgent = {
5
27
  /**
6
28
  * Retrieves an agent based on the specified task.
7
29
  * @param {string} task - The task for which an agent is needed.
8
30
  * @returns {Promise<AgentResponse>} A promise that resolves with the agent details.
9
31
  */
10
- getAgent: (task: string): Promise<any> => {
32
+ findAgent: (task: string, maxResult = 1, agents = [], agentLocaltion: AgentLocation = AgentLocation.ALL, getFrom: FilterUsing.USE_VECTOR_DB): Promise<any> => {
11
33
  return new Promise((resolve, reject) => {
12
34
  cbws.getWebsocket.send(JSON.stringify({
13
35
  "type": "agentEvent",
14
- "action": "getAgentByTask",
15
- "task": task
36
+ "action": "findAgent",
37
+ "task": task,
38
+ "agents": agents,// for filter in vector db
39
+ "maxResult": maxResult,
40
+ "location": agentLocaltion,
41
+ "getFrom": getFrom
16
42
  }));
17
43
  cbws.getWebsocket.on('message', (data: string) => {
18
44
  const response = JSON.parse(data);
19
- if (response.type === "getAgentByTaskResponse") {
45
+ if (response.type === "findAgentByTaskResponse") {
20
46
  resolve(response); // Resolve the Promise with the agent details
21
47
  }
22
48
  });
@@ -43,6 +69,46 @@ const codeboltAgent = {
43
69
  }
44
70
  });
45
71
  });
72
+ },
73
+
74
+ /**
75
+ * Lists all available agents.
76
+ * @returns {Promise<any>} A promise that resolves with the list of agents.
77
+ */
78
+ getAgentsList: (type: Agents = Agents.DOWNLOADED): Promise<any> => {
79
+ return new Promise((resolve, reject) => {
80
+ cbws.getWebsocket.send(JSON.stringify({
81
+ "type": "agentEvent",
82
+ "action": "listAgents",
83
+ "agentType": type,
84
+
85
+ }));
86
+ cbws.getWebsocket.on('message', (data: string) => {
87
+ const response = JSON.parse(data);
88
+ if (response.type === "listAgentsResponse") {
89
+ resolve(response); // Resolve the Promise with the list of agents
90
+ }
91
+ });
92
+ });
93
+ },
94
+ /**
95
+ * Lists all available agents.
96
+ * @returns {Promise<any>} A promise that resolves with the list of agents.
97
+ */
98
+ getAgentsDetail: (agentList = []): Promise<any> => {
99
+ return new Promise((resolve, reject) => {
100
+ cbws.getWebsocket.send(JSON.stringify({
101
+ "type": "agentEvent",
102
+ "action": "agentsDetail",
103
+ "agentList": agentList
104
+ }));
105
+ cbws.getWebsocket.on('message', (data: string) => {
106
+ const response = JSON.parse(data);
107
+ if (response.type === "listAgentsResponse") {
108
+ resolve(response); // Resolve the Promise with the list of agents
109
+ }
110
+ });
111
+ });
46
112
  }
47
113
  }
48
114
 
@@ -0,0 +1,243 @@
1
+ import chatlib from "./../chat"
2
+ import mcp from "./../mcp"
3
+ import llm from "./../llm"
4
+ import codeboltAgent from "./../agent"
5
+ import { SystemPrompt } from "./systemprompt";
6
+ import { TaskInstruction } from "./taskInstruction";
7
+
8
+ interface Message {
9
+ role: 'user' | 'assistant' | 'tool' | 'system';
10
+ content: any[] | string;
11
+ tool_call_id?: string;
12
+ [key: string]: any;
13
+ }
14
+
15
+ interface ToolResult {
16
+ role: 'tool';
17
+ tool_call_id: string;
18
+ content: any;
19
+ }
20
+
21
+ interface ToolDetails {
22
+ toolName: string;
23
+ toolInput: any;
24
+ toolUseId: string;
25
+ }
26
+
27
+ class Agent {
28
+ private tools: any[];
29
+ private subAgents: any[];
30
+ private apiConversationHistory: Message[];
31
+ private maxRun: number;
32
+ private systemPrompt: SystemPrompt;
33
+ private userMessage: Message[];
34
+
35
+
36
+ constructor(tools: any = [], systemPrompt: SystemPrompt, maxRun: number = 0, subAgents: any[] = []) {
37
+ this.tools = tools;
38
+ this.userMessage = [];
39
+ this.apiConversationHistory = [];
40
+ this.maxRun = maxRun;
41
+ this.systemPrompt = systemPrompt;
42
+ this.subAgents = subAgents;
43
+ this.subAgents = subAgents.map(subagent => {
44
+ subagent.function.name = `subagent--${subagent.function.name}`;
45
+ return subagent;
46
+ });
47
+ this.tools = this.tools.concat(subAgents.map(subagent => ({
48
+ ...subagent
49
+ })));
50
+
51
+
52
+ }
53
+
54
+ async run(task: TaskInstruction, successCondition: () => boolean = () => true): Promise<{ success: boolean; error: string | null, message: string | null }> {
55
+
56
+
57
+ let mentaionedMCPSTool: any[] = await task.userMessage.getMentionedMcpsTools();
58
+ this.tools = [
59
+ ...this.tools,
60
+ ...mentaionedMCPSTool
61
+ ]
62
+
63
+
64
+ let completed = false;
65
+ let userMessages = await task.toPrompt();
66
+ this.apiConversationHistory.push({ role: "user", content: userMessages });
67
+ let runcomplete = 0;
68
+ while (!completed && (runcomplete <= this.maxRun || this.maxRun === 0)) {
69
+ try {
70
+ runcomplete++;
71
+ const response = await this.attemptLlmRequest(this.apiConversationHistory, this.tools);
72
+ let isMessagePresentinReply = false;
73
+
74
+ for (const contentBlock of response.choices) {
75
+ if (contentBlock.message) {
76
+ isMessagePresentinReply = true;
77
+ this.apiConversationHistory.push(contentBlock.message);
78
+
79
+ if (contentBlock.message.content != null) {
80
+ await chatlib.sendMessage(contentBlock.message.content, {});
81
+ }
82
+ }
83
+ }
84
+
85
+ if (!isMessagePresentinReply) {
86
+ this.apiConversationHistory.push({
87
+ role: "assistant",
88
+ content: [{ type: "text", text: "Failure: I did not provide a response." }],
89
+ });
90
+ }
91
+
92
+ try {
93
+ let toolResults: ToolResult[] = [];
94
+ let taskCompletedBlock: any;
95
+ let userRejectedToolUse = false;
96
+ const contentBlock = response.choices[0];
97
+
98
+ if (contentBlock.message?.tool_calls) {
99
+ for (const tool of contentBlock.message.tool_calls) {
100
+ const { toolInput, toolName, toolUseId } = this.getToolDetail(tool);
101
+
102
+ if (!userRejectedToolUse) {
103
+ if (toolName.includes("attempt_completion")) {
104
+ taskCompletedBlock = tool;
105
+ } else {
106
+
107
+ let [serverName] = toolName.replace('--', ':').split(':');
108
+
109
+
110
+ if (serverName == 'subagent') {
111
+ console.log("calling agent with params", toolName, toolInput);
112
+
113
+ const agentResponse = await codeboltAgent.startAgent(toolName.replace("subagent--", ''), toolInput.task);
114
+ console.log("got sub agent resonse result", agentResponse);
115
+ const [didUserReject, result] = [false,"tool result is successful"];
116
+ console.log("got sub agent resonse result", didUserReject, result);
117
+
118
+ toolResults.push(this.getToolResult(toolUseId, result));
119
+ if (didUserReject) {
120
+ userRejectedToolUse = true;
121
+ }
122
+ }
123
+ else {
124
+ console.log("calling tool with params", toolName, toolInput);
125
+ const [didUserReject, result] = await this.executeTool(toolName, toolInput);
126
+ console.log("tool result", result);
127
+ toolResults.push(this.getToolResult(toolUseId, result));
128
+
129
+ if (didUserReject) {
130
+ userRejectedToolUse = true;
131
+ }
132
+ }
133
+
134
+ }
135
+ } else {
136
+ toolResults.push(this.getToolResult(toolUseId, "Skipping tool execution due to previous tool user rejection."));
137
+ }
138
+ }
139
+ }
140
+
141
+ if (taskCompletedBlock) {
142
+ let [_, result] = await this.executeTool(
143
+ taskCompletedBlock.function.name,
144
+ JSON.parse(taskCompletedBlock.function.arguments || "{}")
145
+ );
146
+
147
+ if (result === "") {
148
+ completed = true;
149
+ result = "The user is satisfied with the result.";
150
+ }
151
+ toolResults.push(this.getToolResult(taskCompletedBlock.id, result));
152
+ }
153
+
154
+ this.apiConversationHistory.push(...toolResults);
155
+ let nextUserMessage: Message[] = toolResults;
156
+
157
+ if (toolResults.length === 0) {
158
+ nextUserMessage = [{
159
+ role: "user",
160
+ content: [{
161
+ type: "text",
162
+ text: "If you have completed the user's task, use the attempt_completion tool. If you require additional information from the user, use the ask_followup_question tool. Otherwise, if you have not completed the task and do not need additional information, then proceed with the next step of the task. (This is an automated message, so do not respond to it conversationally.)"
163
+ }]
164
+ }];
165
+
166
+ if (nextUserMessage) {
167
+ this.apiConversationHistory.push(nextUserMessage[0]);
168
+ }
169
+ }
170
+ } catch (error) {
171
+ console.error("Error in agent tool call:", error);
172
+ return { success: false, error: error instanceof Error ? error.message : String(error), message: null };
173
+ }
174
+ } catch (error) {
175
+ console.error("Error in agent tool call:", error);
176
+ return { success: false, error: error instanceof Error ? error.message : String(error), message: null };
177
+ }
178
+ }
179
+
180
+ return {
181
+ success: completed,
182
+ error: null,
183
+ message: this.apiConversationHistory
184
+ .filter(msg => msg.role === 'assistant')
185
+ .pop()?.content as string || ''
186
+ };
187
+ }
188
+
189
+ private async attemptLlmRequest(apiConversationHistory: Message[], tools: Record<string, any>): Promise<any> {
190
+
191
+
192
+ try {
193
+ let systemPrompt = await this.systemPrompt.toPromptText();
194
+ const aiMessages: Message[] = [
195
+ { role: "system", content: systemPrompt },
196
+ ...apiConversationHistory,
197
+ ];
198
+
199
+ const createParams = {
200
+ full: true,
201
+ messages: aiMessages,
202
+ tools: tools,
203
+ tool_choice: "auto",
204
+ };
205
+ //@ts-ignore
206
+ const { completion } = await llm.inference(createParams);
207
+ return completion;
208
+ } catch (error) {
209
+ console.log(error);
210
+ return this.attemptApiRequest();
211
+ }
212
+ }
213
+
214
+ private async executeTool(toolName: string, toolInput: any): Promise<[boolean, any]> {
215
+ return mcp.executeTool(toolName, toolInput);
216
+ }
217
+ private async startSubAgent(agentName: string, params: any): Promise<[boolean, any]> {
218
+ return codeboltAgent.startAgent(agentName, params.task);
219
+ }
220
+
221
+ private getToolDetail(tool: any): ToolDetails {
222
+ return {
223
+ toolName: tool.function.name,
224
+ toolInput: JSON.parse(tool.function.arguments || "{}"),
225
+ toolUseId: tool.id
226
+ };
227
+ }
228
+
229
+ private getToolResult(tool_call_id: string, content: any): ToolResult {
230
+ return {
231
+ role: "tool",
232
+ tool_call_id,
233
+ content,
234
+ };
235
+ }
236
+
237
+ // Placeholder for error fallback method
238
+ private attemptApiRequest(): any {
239
+ throw new Error("API request fallback not implemented");
240
+ }
241
+ }
242
+
243
+ export { Agent };