psadk 1.1.0

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +205 -0
  4. package/build/main/index.d.ts +6 -0
  5. package/build/main/index.js +23 -0
  6. package/build/main/lib/ILogger.d.ts +9 -0
  7. package/build/main/lib/ILogger.js +25 -0
  8. package/build/main/lib/PSAI.d.ts +29 -0
  9. package/build/main/lib/PSAI.js +383 -0
  10. package/build/main/lib/PSAgent.d.ts +215 -0
  11. package/build/main/lib/PSAgent.js +990 -0
  12. package/build/main/lib/PSAgentConfig.d.ts +23 -0
  13. package/build/main/lib/PSAgentConfig.js +3 -0
  14. package/build/main/lib/PSAgentLogger.d.ts +13 -0
  15. package/build/main/lib/PSAgentLogger.js +33 -0
  16. package/build/main/lib/PSAgentTask.d.ts +12 -0
  17. package/build/main/lib/PSAgentTask.js +30 -0
  18. package/build/main/lib/PSAgentTool.d.ts +56 -0
  19. package/build/main/lib/PSAgentTool.js +84 -0
  20. package/build/main/lib/ai.d.ts +11 -0
  21. package/build/main/lib/ai.js +127 -0
  22. package/build/main/lib/async.d.ts +20 -0
  23. package/build/main/lib/async.js +36 -0
  24. package/build/main/lib/getServiceToken.d.ts +1 -0
  25. package/build/main/lib/getServiceToken.js +3 -0
  26. package/build/main/lib/jwt.d.ts +41 -0
  27. package/build/main/lib/jwt.js +73 -0
  28. package/build/main/lib/number.d.ts +43 -0
  29. package/build/main/lib/number.js +56 -0
  30. package/build/main/lib/tools/PSAentTool.d.ts +7 -0
  31. package/build/main/lib/tools/PSAentTool.js +78 -0
  32. package/build/main/lib/tools/PSArtifactTool copy.d.ts +7 -0
  33. package/build/main/lib/tools/PSArtifactTool copy.js +78 -0
  34. package/build/main/lib/tools/PSArtifactTool.d.ts +7 -0
  35. package/build/main/lib/tools/PSArtifactTool.js +79 -0
  36. package/build/main/lib/tools/PSSubAgentTool.d.ts +20 -0
  37. package/build/main/lib/tools/PSSubAgentTool.js +163 -0
  38. package/build/module/index.d.ts +6 -0
  39. package/build/module/index.js +7 -0
  40. package/build/module/lib/PSAI.d.ts +25 -0
  41. package/build/module/lib/PSAI.js +314 -0
  42. package/build/module/lib/PSAgent.d.ts +215 -0
  43. package/build/module/lib/PSAgent.js +992 -0
  44. package/build/module/lib/async.d.ts +20 -0
  45. package/build/module/lib/async.js +32 -0
  46. package/build/module/lib/number.d.ts +43 -0
  47. package/build/module/lib/number.js +51 -0
  48. package/package.json +122 -0
@@ -0,0 +1,990 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PSAgent = void 0;
7
+ exports.sleep = sleep;
8
+ /* eslint-disable @typescript-eslint/no-explicit-any */
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_os_1 = __importDefault(require("node:os"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const server_1 = require("@a2a-js/sdk/server");
13
+ const express_1 = require("@a2a-js/sdk/server/express");
14
+ const express_2 = __importDefault(require("express"));
15
+ const fetch_retry_1 = __importDefault(require("fetch-retry"));
16
+ const uuid_1 = require("uuid"); // For generating unique IDs
17
+ const yaml_1 = __importDefault(require("yaml"));
18
+ const v4_1 = require("zod/v4");
19
+ const PSAI_1 = require("./PSAI");
20
+ const PSAgentTask_1 = require("./PSAgentTask");
21
+ const PSAgentTool_1 = require("./PSAgentTool");
22
+ // fetch-retry can also wrap Node.js's native fetch API implementation:
23
+ const fetch = (0, fetch_retry_1.default)(global.fetch);
24
+ async function sleep(ms) {
25
+ return new Promise((resolve) => setTimeout(resolve, ms));
26
+ }
27
+ /**
28
+ * PSAgent class to manage AI agents with tools and tasks
29
+ * Implements AgentExecutor interface from A2A SDK
30
+ * Supports starting, resuming, cancelling agents and executing tools
31
+ * Manages agent state, tools, tasks and interactions with A2A platform
32
+ * Includes methods for A2A server setup and event fetching
33
+ *
34
+ * uses the token from config if not PS_API_TOKEN env variable
35
+ * adds x-client-id, x-project-id, x-workspace-id from env variables
36
+ * PS_CLIENT_ID, PS_PROJECT_ID, PS_WORKSPACE_ID respectively for authentication headers
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * import { PSAI, PSAgent, PSAgentLogger } from 'psadk';
41
+ * import dotenv from 'dotenv';
42
+ * dotenv.config();
43
+ * async function main() {
44
+ * const token = await PSAI.getServiceToken({});
45
+ * const HelloAgent = new PSAgent({
46
+ * name: 'HelloAgent',
47
+ * description: 'A simple hello world agent',
48
+ * system_prompt: 'You are a helpful assistant that greets users.',
49
+ * model: 'gpt-5',
50
+ * tools: [],
51
+ * log: new PSAgentLogger({ level: 'info' }),
52
+ * token: token,
53
+ * port: 41241,
54
+ * });
55
+ * const { app, port } = HelloAgent.getA2AServer();
56
+ * app.listen(port, () => {
57
+ * console.log('HelloAgent is running on http://localhost:${port}');
58
+ * });
59
+ * }
60
+ * main();
61
+ * ```
62
+ * @see PSAgentConfig, PSAgentTool, PSAgentTask
63
+ *
64
+ * @see
65
+ * https://dev.lionis.ai/docs/api/v1/agents/create-agent
66
+ * https://pscode.lioncloud.net/ai-tso/psadk_samples
67
+ * https://a2aproject.com/docs/getting-started/quickstart
68
+ *
69
+ */
70
+ class PSAgent {
71
+ /**
72
+ * create a new PSAgent with the given config
73
+ * @param config PSAgentConfig with optional logger
74
+ */
75
+ constructor(config) {
76
+ this.tools = [];
77
+ this.tasks = [];
78
+ this.cancelledTasks = new Set();
79
+ this.cancelTask = async (taskId) => {
80
+ this.cancelledTasks.add(taskId);
81
+ // The execute loop is responsible for publishing the final state
82
+ };
83
+ this.config = config;
84
+ this.log = config.log;
85
+ }
86
+ /**
87
+ * Get the Agent Class
88
+ * @returns Agent class from config or default "LlmAgent"
89
+ */
90
+ get AgentClass() {
91
+ return this.config.agent_class || "LlmAgent";
92
+ }
93
+ /**
94
+ * Get the Name of the Agent
95
+ *
96
+ * @returns Name of the agent from config
97
+ */
98
+ get Name() {
99
+ return this.config.name;
100
+ }
101
+ /**
102
+ * Get the Description of the Agent
103
+ * @returns Description of the agent from config
104
+ */
105
+ get Description() {
106
+ return this.config.description;
107
+ }
108
+ /**
109
+ * Get the Instruction(System Prompt) of the Agent
110
+ * @returns Instruction(System prompt) of the agent from config
111
+ */
112
+ get Instruction() {
113
+ return this.config.instruction;
114
+ }
115
+ /**
116
+ * Get the Model of the Agent
117
+ * @returns Model of the agent from config
118
+ */
119
+ get Model() {
120
+ return this.config.model;
121
+ }
122
+ /**
123
+ * Get the Input Schema of the Agent
124
+ * @returns Input schema of the agent from config
125
+ */
126
+ get InputSchema() {
127
+ return this.config.input_schema;
128
+ }
129
+ /**
130
+ * Get the Output Schema of the Agent
131
+ * @returns Output schema of the agent from config
132
+ */
133
+ get OutputSchema() {
134
+ return this.config.output_schema;
135
+ }
136
+ /**
137
+ * Get the Token for the Agent
138
+ * @returns Token of the agent from config
139
+ */
140
+ get Token() {
141
+ return this.config.token;
142
+ }
143
+ /**
144
+ * Set the Token for the Agent
145
+ * @param value Token string to set in config
146
+ */
147
+ set Token(value) {
148
+ this.config.token = value;
149
+ }
150
+ /**
151
+ * Get the Tools for the Agent
152
+ * Includes both config tools and dynamically added tools
153
+ * @returns Array of PSAgentTool instances
154
+ */
155
+ get Tools() {
156
+ return [...this.config.tools || [], ...this.tools];
157
+ }
158
+ /**
159
+ * Get the Tasks for the Agent
160
+ * Includes both config tasks and dynamically added tasks
161
+ * @returns Array of PSAgentTask instances
162
+ */
163
+ get Tasks() {
164
+ return [...this.config.tasks || [], ...this.tasks];
165
+ }
166
+ /**
167
+ * Get the Agent ID after starting the agent
168
+ * @returns Agent ID string or undefined if not started
169
+ */
170
+ get AgentId() {
171
+ return this.agentId;
172
+ }
173
+ /**
174
+ * Get the Correlation ID after starting the agent
175
+ * @returns Correlation ID string or undefined if not started
176
+ */
177
+ get CorrelationId() {
178
+ return this.correlationId;
179
+ }
180
+ /**
181
+ * Add tools to the agent dynamically
182
+ * @param tool PSAgentTool to add to the agent
183
+ */
184
+ addTool(tool) {
185
+ var _a;
186
+ if (!this.tools) {
187
+ this.tools = [];
188
+ }
189
+ let toolIndex = ((_a = this.config.tools) === null || _a === void 0 ? void 0 : _a.findIndex(t => t.Name === tool.Name)) || -1;
190
+ if (toolIndex !== -1) {
191
+ throw new Error(`Tool with name ${tool.Name} already exists in config`);
192
+ }
193
+ toolIndex = this.tools.findIndex(t => t.Name === tool.Name);
194
+ if (toolIndex !== -1) {
195
+ throw new Error(`Tool with name ${tool.Name} already exists in agent`);
196
+ }
197
+ else {
198
+ this.tools.push(tool);
199
+ }
200
+ }
201
+ // get token from config or environment variable
202
+ async getToken() {
203
+ if (this.config.token)
204
+ return this.config.token;
205
+ if (this.config.getToken)
206
+ return await this.config.getToken();
207
+ return process.env.PS_API_TOKEN || '';
208
+ }
209
+ // Private method to get auth headers
210
+ // uses the token from config if not PS_API_TOKEN env variable
211
+ // adds x-client-id, x-project-id, x-workspace-id from env variables
212
+ // PS_CLIENT_ID, PS_PROJECT_ID, PS_WORKSPACE_ID respectively
213
+ async getAuthHeaders() {
214
+ const headers = {};
215
+ headers['Authorization'] = `Bearer ${await this.getToken()}`;
216
+ headers["x-client-id"] = process.env.PS_CLIENT_ID || "";
217
+ headers["x-project-id"] = process.env.PS_PROJECT_ID || "";
218
+ headers["x-workspace-id"] = process.env.PS_WORKSPACE_ID || "";
219
+ if (this.config.additional_headers) {
220
+ Object.assign(headers, this.config.additional_headers);
221
+ }
222
+ return headers;
223
+ }
224
+ // Get base URL from environment variable or use default
225
+ // uses env variable PS_API_URL if set, otherwise defaults to https://dev.lionis.ai
226
+ getBaseUrl() {
227
+ const baseUrl = process.env.PS_API_URL || 'https://dev.lionis.ai';
228
+ return baseUrl.replace(/\/+$/, ''); // Remove trailing slashes
229
+ }
230
+ /**
231
+ * start a new temp agent on the agent platform
232
+ * @param input input to the agent the schema should match InputSchema if provided
233
+ * @param history history of messages for agent context
234
+ * @param log logger to use for logging, defaults to agent's logger
235
+ * @returns Correlation ID of the started agent
236
+ */
237
+ async start(input, history, log) {
238
+ log = log || this.log;
239
+ const ischema = this.InputSchema ? this.InputSchema : v4_1.z.toJSONSchema(v4_1.z.object({
240
+ query: v4_1.z.string().meta({
241
+ title: "query",
242
+ description: "The query by the user."
243
+ }),
244
+ // history: z.array(z.object({
245
+ // role: z.enum(["user", "model"]).meta({
246
+ // title: "role",
247
+ // description: "Role of the message sender"
248
+ // }),
249
+ // content: z.string().meta({
250
+ // title: "content",
251
+ // description: "Content of the message"
252
+ // })
253
+ // })).optional().meta({
254
+ // title: "history",
255
+ // description: "List of the User and Assistant chat history"
256
+ // })
257
+ }).meta({
258
+ title: "request_body",
259
+ description: "The request body parameters for the agent.",
260
+ }), { "io": "input" });
261
+ //check if the input confirms to the input schema
262
+ // const parseResult = z.object(ischema).safeParse(input);
263
+ // if (!parseResult.success) {
264
+ // log?.error('Input validation failed:', parseResult.error.message);
265
+ // throw new Error(`Input validation failed: ${parseResult.error.issues.map(issue=>issue.message).join(', ')}`);
266
+ // }
267
+ if (ischema.properties) {
268
+ Object.assign(ischema.properties, {
269
+ history: {
270
+ type: "array",
271
+ items: {
272
+ type: "object"
273
+ },
274
+ description: "List of the User and Assistant chat history",
275
+ title: "Chat history"
276
+ }
277
+ });
278
+ }
279
+ // console.log("input schema:", JSON.stringify(ischema, null, 2));
280
+ const output_schema = this.OutputSchema || v4_1.z.toJSONSchema(v4_1.z.object({
281
+ response: v4_1.z.string().meta({
282
+ title: "Response",
283
+ description: "The response from the agent",
284
+ }),
285
+ }).meta({
286
+ title: "Agent_Response",
287
+ description: "The response from the agent after processing the input",
288
+ }), { io: "output" });
289
+ const body = {
290
+ agent: {
291
+ name: this.Name,
292
+ description: this.Description,
293
+ system_prompt: this.Instruction,
294
+ llm: this.Model || "gpt-5",
295
+ input_schema: ischema,
296
+ output_schema: output_schema,
297
+ },
298
+ input_params: Object.assign(input, { history: history || [] }),
299
+ tasks: this.Tasks.map(task => ({
300
+ name: task.Name,
301
+ description: task.Description
302
+ })),
303
+ tools: {
304
+ new_tools: this.Tools.map(tool => ({
305
+ name: tool.Name,
306
+ description: tool.Description,
307
+ type: tool.Type,
308
+ local_execution: tool.LocalExecution,
309
+ hitl: tool.HITL,
310
+ inputs: tool.Inputs
311
+ })),
312
+ existing_tool_ids: []
313
+ },
314
+ planning: {
315
+ plan_required: this.config.show_plan || false,
316
+ hitl: this.config.hitl_for_plan || false
317
+ },
318
+ };
319
+ console.log(`Starting agent with body: ${JSON.stringify(body, null, 2)}`);
320
+ try {
321
+ const headers = await this.getAuthHeaders();
322
+ // log?.debug('Starting agent with headers:', headers);
323
+ // log?.debug('Starting agent with body:', JSON.stringify(body.input_params, null, 2));
324
+ const response = await fetch(`${this.getBaseUrl()}/api/v1/agents/temp_agent`, {
325
+ method: 'POST',
326
+ headers: Object.assign({ 'Content-Type': 'application/json' }, headers),
327
+ body: JSON.stringify(body),
328
+ retries: 3,
329
+ retryOn: function (attempt, error, response) {
330
+ // retry on any network error, or 4xx or 5xx status codes
331
+ if (error !== null || response.status > 400 && attempt < 4) {
332
+ log === null || log === void 0 ? void 0 : log.warn(`retrying execute agent, attempt number ${attempt + 1}, status: ${response.status}`, error);
333
+ return true;
334
+ }
335
+ return false;
336
+ },
337
+ retryDelay: function (attempt) {
338
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
339
+ }
340
+ });
341
+ if (!response.ok) {
342
+ let errorDetails;
343
+ try {
344
+ errorDetails = await response.text();
345
+ }
346
+ catch (e) {
347
+ throw new Error(`Unable to start agent. status: ${response.status}. ${e}`);
348
+ }
349
+ if (errorDetails) {
350
+ throw new Error(`Unable to start agent. status: ${response.status}, details: ${JSON.stringify(errorDetails, null, 2)}`);
351
+ }
352
+ }
353
+ const responseData = (await response.json());
354
+ this.agentId = responseData.data.agent_id;
355
+ this.correlationId = responseData.data.correlation_id;
356
+ log === null || log === void 0 ? void 0 : log.info(`Agent started with ID: ${this.agentId}, Correlation ID: ${this.correlationId}`);
357
+ return this.correlationId;
358
+ }
359
+ catch (error) {
360
+ log === null || log === void 0 ? void 0 : log.error('Unable to start agent:', error);
361
+ throw error;
362
+ }
363
+ }
364
+ /**
365
+ * resume the agent with tool output after a tool execution or human input
366
+ * @param tooloutput output from the tool execution to send back to the agent
367
+ * @returns
368
+ */
369
+ async resume(tooloutput) {
370
+ const log = this.log;
371
+ if (!this.agentId) {
372
+ throw new Error("Agent ID is not set");
373
+ }
374
+ try {
375
+ const response = await fetch(`${this.getBaseUrl()}/api/v1/agents/${this.agentId}/resume`, {
376
+ method: 'POST',
377
+ headers: Object.assign({ 'Content-Type': 'application/json' }, await this.getAuthHeaders()),
378
+ body: JSON.stringify({
379
+ "correlation_id": this.CorrelationId,
380
+ "tool_output_override": tooloutput,
381
+ }),
382
+ retries: 3,
383
+ retryOn: function (attempt, error, response) {
384
+ // retry on any network error, or 4xx or 5xx status codes
385
+ if (error !== null || response.status >= 400 && attempt < 4) {
386
+ log === null || log === void 0 ? void 0 : log.warn(`retrying resume, attempt number ${attempt + 1} ${response.status}`, error);
387
+ return true;
388
+ }
389
+ return false;
390
+ },
391
+ retryDelay: function (attempt) {
392
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
393
+ }
394
+ });
395
+ if (!response.ok) {
396
+ log === null || log === void 0 ? void 0 : log.error("Error resuming agent:", await response.json());
397
+ throw new Error(`HTTP error! status: ${response.status}`);
398
+ }
399
+ const resumeData = await response.json();
400
+ return resumeData;
401
+ }
402
+ catch (error) {
403
+ log === null || log === void 0 ? void 0 : log.error("Error resuming agent:", error);
404
+ log === null || log === void 0 ? void 0 : log.error("Correlation ID:", this.correlationId);
405
+ log === null || log === void 0 ? void 0 : log.error("Tool Output:", tooloutput);
406
+ throw new Error(`Failed to resume agent: ${error instanceof Error ? error.message : String(error)}`);
407
+ }
408
+ }
409
+ /**
410
+ * deletes the agent running on the platform
411
+ * @param log optional logger to use for logging, defaults to agent's logger
412
+ */
413
+ async cancel(log) {
414
+ if (!this.AgentId) {
415
+ throw new Error("Agent is not started");
416
+ }
417
+ try {
418
+ const response = await fetch(`${this.getBaseUrl()}/api/v1/agents/${this.agentId}`, {
419
+ method: 'DELETE',
420
+ headers: Object.assign({ 'Content-Type': 'application/json' }, await this.getAuthHeaders()),
421
+ retries: 3,
422
+ retryOn: function (attempt, error, response) {
423
+ // retry on any network error, or 4xx or 5xx status codes
424
+ if (error !== null || response.status >= 400 && attempt < 4) {
425
+ log === null || log === void 0 ? void 0 : log.warn(`retrying cancel agent, attempt number ${attempt + 1}`);
426
+ return true;
427
+ }
428
+ return false;
429
+ },
430
+ retryDelay: function (attempt) {
431
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
432
+ }
433
+ });
434
+ if (!response.ok) {
435
+ let errorDetails;
436
+ try {
437
+ errorDetails = await response.json();
438
+ log === null || log === void 0 ? void 0 : log.error((await response.json()));
439
+ }
440
+ catch (e) {
441
+ throw new Error(`Unable to cancel agent status: ${response.status}, ${e}`);
442
+ }
443
+ if (errorDetails) {
444
+ throw new Error(`Unable to cancel agent status: ${response.status}, details: ${JSON.stringify(errorDetails)}`);
445
+ }
446
+ }
447
+ log === null || log === void 0 ? void 0 : log.info(`Agent ${this.agentId} cancelled successfully`);
448
+ }
449
+ catch (error) {
450
+ log === null || log === void 0 ? void 0 : log.error('Error cancelling agent:', error);
451
+ throw error;
452
+ }
453
+ }
454
+ /**
455
+ * Gets all the events for the current agent run identified correlation ID
456
+ * @returns Array of event objects for the current agent's correlation ID
457
+ * @see https://dev.lionis.ai/api/v1/events/events?correlationId={{correlation_id}}
458
+ */
459
+ async getEvents() {
460
+ if (!this.CorrelationId) {
461
+ throw new Error("Correlation ID is not set");
462
+ }
463
+ try {
464
+ const response = await fetch(`${this.getBaseUrl()}/api/v1/events/events?correlationId=${this.correlationId}`, {
465
+ method: 'GET',
466
+ headers: Object.assign({ 'Content-Type': 'application/json' }, await this.getAuthHeaders()),
467
+ retries: 3,
468
+ retryOn: function (attempt, error, response) {
469
+ // retry on any network error, or 4xx or 5xx status codes
470
+ if (error !== null || response.status >= 400 && attempt < 4) {
471
+ //log?.warn(`retrying getEvents, attempt number ${attempt + 1}`);
472
+ return true;
473
+ }
474
+ return false;
475
+ },
476
+ retryDelay: function (attempt) {
477
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
478
+ }
479
+ });
480
+ if (!response.ok) {
481
+ //log.error("Error fetching agent events:", await response.json());
482
+ throw new Error(`HTTP error! status: ${response.status}`);
483
+ }
484
+ const eventsData = await response.json();
485
+ return eventsData;
486
+ }
487
+ catch (error) {
488
+ //log.error("Error fetching agent events:", error);
489
+ throw new Error(`Failed to fetch agent events: ${error instanceof Error ? error.message : String(error)}`);
490
+ }
491
+ }
492
+ /**
493
+ * Invoke the tool with the given name and input
494
+ * @remarks
495
+ * The input object should match the tool's input schema
496
+ *
497
+ * @param toolName name of the tool to execute
498
+ * @param input input object for the tool execution should match tool's input schema
499
+ * @param log logger to use for logging, defaults to agent's logger
500
+ * @returns output from the tool execution or error if any
501
+ *
502
+ * @example
503
+ * Example input for PSArtifactTool:
504
+ * ```json
505
+ * {
506
+ * "name": "example_artifact",
507
+ * "action": "write",
508
+ * "content": "This is an example artifact content."
509
+ * }
510
+ * ```
511
+ */
512
+ async executeTool(toolName, input, log) {
513
+ const results = { error: null };
514
+ const tool = this.Tools.find(t => t.Name === toolName);
515
+ if (!tool) {
516
+ results.error = new Error(`Tool with name ${toolName} not found`);
517
+ }
518
+ else {
519
+ try {
520
+ results.result = await tool.run(input, log);
521
+ }
522
+ catch (error) {
523
+ results.result = undefined;
524
+ results.error = new Error(`${error instanceof Error ? error.message : String(error)}`);
525
+ }
526
+ }
527
+ try {
528
+ if (results.error) {
529
+ await this.resume({ error: results.error.message || results.error.toString() });
530
+ }
531
+ else {
532
+ await this.resume(results.result || { output: "No result returned from tool execution" });
533
+ }
534
+ }
535
+ catch (error) {
536
+ results.error = new Error(`Error resuming agent after tool execution: ${error instanceof Error ? error.message : String(error)}`);
537
+ }
538
+ return results;
539
+ }
540
+ /**
541
+ *
542
+ * @param requestContext
543
+ * @param eventBus
544
+ * @returns
545
+ */
546
+ async execute(requestContext, eventBus) {
547
+ var _a;
548
+ const log = this.log;
549
+ const userMessage = requestContext.userMessage;
550
+ const existingTask = requestContext.task;
551
+ const taskId = (existingTask === null || existingTask === void 0 ? void 0 : existingTask.id) || (0, uuid_1.v4)();
552
+ const contextId = userMessage.contextId || (existingTask === null || existingTask === void 0 ? void 0 : existingTask.contextId) || (0, uuid_1.v4)();
553
+ log === null || log === void 0 ? void 0 : log.info(`[${this.Name}:AgentExecutor] Processing message ${userMessage.messageId} for task ${taskId} (context: ${contextId})`);
554
+ // 1. Publish initial Task event if it's a new task
555
+ if (!existingTask) {
556
+ const initialTask = {
557
+ kind: 'task',
558
+ id: taskId,
559
+ contextId: contextId,
560
+ status: {
561
+ state: 'submitted',
562
+ timestamp: new Date().toISOString(),
563
+ },
564
+ history: [userMessage],
565
+ metadata: userMessage.metadata,
566
+ artifacts: [], // Initialize artifacts array
567
+ };
568
+ eventBus.publish(initialTask);
569
+ }
570
+ // 2. Publish "working" status update
571
+ let workingStatusUpdate = {
572
+ kind: 'status-update',
573
+ taskId: taskId,
574
+ contextId: contextId,
575
+ status: {
576
+ state: 'working',
577
+ message: {
578
+ kind: 'message',
579
+ role: 'agent',
580
+ messageId: (0, uuid_1.v4)(),
581
+ parts: [{ kind: 'text', text: 'Initializing the agent...' }],
582
+ taskId: taskId,
583
+ contextId: contextId,
584
+ },
585
+ timestamp: new Date().toISOString(),
586
+ },
587
+ final: false,
588
+ };
589
+ eventBus.publish(workingStatusUpdate);
590
+ // 3. Prepare messages for history
591
+ const history = (existingTask === null || existingTask === void 0 ? void 0 : existingTask.history) ? [...existingTask.history] : [];
592
+ if (!history.find(m => m.messageId === userMessage.messageId)) {
593
+ history.push(userMessage);
594
+ }
595
+ log === null || log === void 0 ? void 0 : log.debug(`[${this.Name}:AgentExecutor] Total messages in history: ${history.length}`);
596
+ const messages = history
597
+ .map((m) => ({
598
+ role: (m.role === 'agent' ? 'model' : 'user'),
599
+ content: m.parts
600
+ .filter((p) => p.kind === 'text' && !!p.text)
601
+ .map((p) => p.text).join('\n'),
602
+ // .map((p) => ({
603
+ // text: (p as TextPart).text,
604
+ // })),
605
+ }))
606
+ .filter((m) => m.content.length > 0);
607
+ if (messages.length === 0) {
608
+ log === null || log === void 0 ? void 0 : log.warn(`[${this.Name}:AgentExecutor] No valid text messages found in history for task ${taskId}.`);
609
+ const failureUpdate = {
610
+ kind: 'status-update',
611
+ taskId: taskId,
612
+ contextId: contextId,
613
+ status: {
614
+ state: 'failed',
615
+ message: {
616
+ kind: 'message',
617
+ role: 'agent',
618
+ messageId: (0, uuid_1.v4)(),
619
+ parts: [{ kind: 'text', text: 'No input message found to process.' }],
620
+ taskId: taskId,
621
+ contextId: contextId,
622
+ },
623
+ timestamp: new Date().toISOString(),
624
+ },
625
+ final: true,
626
+ };
627
+ eventBus.publish(failureUpdate);
628
+ return;
629
+ }
630
+ try {
631
+ const input = {};
632
+ if (userMessage.parts && userMessage.parts.length > 0) {
633
+ for (const part of userMessage.parts) {
634
+ if (part.kind === 'text' && part.text) {
635
+ input['query'] = part.text;
636
+ }
637
+ // TODO: handle other part kinds (e.g., images, files) here as needed
638
+ }
639
+ }
640
+ if (this.Tools.length === 0) {
641
+ const ai = new PSAI_1.PSAI(this.Token || '', this.getBaseUrl(), log);
642
+ const llmResponse = await ai.llm(input.query, this.Model);
643
+ //console.log("llmResponse:", llmResponse);
644
+ const completedUpdate = {
645
+ kind: 'status-update',
646
+ taskId: taskId,
647
+ contextId: contextId,
648
+ status: {
649
+ state: 'completed',
650
+ message: {
651
+ kind: 'message',
652
+ role: 'agent',
653
+ messageId: (0, uuid_1.v4)(),
654
+ parts: [{ kind: 'text', text: llmResponse.choices[0].message.content }],
655
+ taskId: taskId,
656
+ contextId: contextId,
657
+ },
658
+ timestamp: new Date().toISOString(),
659
+ },
660
+ final: true,
661
+ };
662
+ eventBus.publish(completedUpdate);
663
+ return;
664
+ }
665
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.debug(`Agent input: ${JSON.stringify(input)}`);
666
+ await this.start(input, messages.slice(0, -1), log);
667
+ workingStatusUpdate = {
668
+ kind: 'status-update',
669
+ taskId: taskId,
670
+ contextId: contextId,
671
+ status: {
672
+ state: 'working',
673
+ message: {
674
+ kind: 'message',
675
+ role: 'agent',
676
+ messageId: (0, uuid_1.v4)(),
677
+ parts: [{ kind: 'text', text: `started new agent ${this.AgentId}, correlationid: ${this.correlationId}` }],
678
+ taskId: taskId,
679
+ contextId: contextId,
680
+ },
681
+ timestamp: new Date().toISOString(),
682
+ },
683
+ final: false,
684
+ };
685
+ eventBus.publish(workingStatusUpdate);
686
+ let events;
687
+ let lastevent = {
688
+ timestamp: Date.now(),
689
+ };
690
+ let processedEvents = 0;
691
+ do {
692
+ do {
693
+ if (this.cancelledTasks.has(taskId)) {
694
+ log === null || log === void 0 ? void 0 : log.info(`[${this.Name}:AgentExecutor] Task ${taskId} has been cancelled.`);
695
+ // Publish the final 'canceled' status.
696
+ const cancelledUpdate = {
697
+ kind: "status-update",
698
+ taskId: taskId,
699
+ contextId: contextId,
700
+ status: { state: "canceled", timestamp: new Date().toISOString() },
701
+ final: true,
702
+ };
703
+ eventBus.publish(cancelledUpdate);
704
+ eventBus.finished();
705
+ // Clean up and exit.
706
+ this.cancelledTasks.delete(taskId);
707
+ return;
708
+ }
709
+ await sleep(500);
710
+ //log?.info(`[${this.Name}:AgentExecutor] Fetching events for correlation ID ${this.CorrelationId}`);
711
+ events = await this.getEvents();
712
+ if (events.length > processedEvents) {
713
+ events = events.slice(processedEvents); // get only new events
714
+ }
715
+ } while (events.length === 0);
716
+ const event = events[0];
717
+ if (lastevent.timestamp !== event.timestamp) {
718
+ //log?.debug(`[${this.Name}:AgentExecutor] New event: ${event.timestamp} Last Event: ${lastevent.timestamp} `);
719
+ lastevent = event;
720
+ if (lastevent.agentStatus === "waiting") {
721
+ if (lastevent.tool.startsWith('mcp_')) {
722
+ //TODO: handle mcp tools
723
+ log === null || log === void 0 ? void 0 : log.info(`[${this.Name}:AgentExecutor] waiting for mcp tool ${lastevent.tool} to complete...`);
724
+ }
725
+ else if (lastevent.tool) {
726
+ log === null || log === void 0 ? void 0 : log.info(`[${this.Name}:AgentExecutor] toolcall: ${lastevent.tool}, ts:${lastevent.timestamp}, c:${processedEvents}\n`);
727
+ let workingStatusUpdate = {
728
+ kind: 'status-update',
729
+ taskId: taskId,
730
+ contextId: contextId,
731
+ status: {
732
+ state: 'working',
733
+ message: {
734
+ kind: 'message',
735
+ role: 'agent',
736
+ messageId: (0, uuid_1.v4)(),
737
+ parts: [{ kind: 'text', text: `invoking tool ${lastevent.tool}(${JSON.stringify(lastevent.toolInput.request_body)})...\n` }],
738
+ taskId: taskId,
739
+ contextId: contextId,
740
+ metadata: {
741
+ data: lastevent.toolInput.request_body
742
+ }
743
+ },
744
+ timestamp: new Date().toISOString(),
745
+ },
746
+ final: false,
747
+ };
748
+ eventBus.publish(workingStatusUpdate);
749
+ const res = await this.executeTool(lastevent.tool, lastevent.toolInput.request_body, log);
750
+ let statusMsg = `Tool ${lastevent.tool} executed `;
751
+ if (res.error) {
752
+ log === null || log === void 0 ? void 0 : log.error(`${res.error}`);
753
+ statusMsg += `with error: ${res.error.message || res.error.toString()}`;
754
+ }
755
+ else {
756
+ statusMsg += `successfully.`;
757
+ }
758
+ workingStatusUpdate = {
759
+ kind: 'status-update',
760
+ taskId: taskId,
761
+ contextId: contextId,
762
+ status: {
763
+ state: 'working',
764
+ message: {
765
+ kind: 'message',
766
+ role: 'agent',
767
+ messageId: (0, uuid_1.v4)(),
768
+ parts: [{ kind: 'text', text: statusMsg }],
769
+ taskId: taskId,
770
+ contextId: contextId,
771
+ },
772
+ timestamp: new Date().toISOString(),
773
+ },
774
+ final: false,
775
+ };
776
+ eventBus.publish(workingStatusUpdate);
777
+ }
778
+ }
779
+ else if (lastevent.agentStatus === "pending") {
780
+ //log(`\n\n#### ${lastevent.agentStatus}:\n`);
781
+ }
782
+ else if (lastevent.agentStatus === "in-progress") {
783
+ if (lastevent.tool === 'generate_plan_tool' && lastevent.toolOutput) {
784
+ log === null || log === void 0 ? void 0 : log.info("```log-Agent_Plan\n" + lastevent.toolOutput + "\n```");
785
+ }
786
+ else if (lastevent.message.indexOf("resume")) {
787
+ //log.info(`.`);
788
+ }
789
+ else
790
+ log === null || log === void 0 ? void 0 : log.info(`\n\n#### ${lastevent.message}:\n`);
791
+ }
792
+ else if (lastevent.agentStatus === "completed") {
793
+ log === null || log === void 0 ? void 0 : log.info(`Agent Execution Completed`);
794
+ log === null || log === void 0 ? void 0 : log.info(`---`);
795
+ log === null || log === void 0 ? void 0 : log.done(lastevent.output.response);
796
+ }
797
+ else {
798
+ log === null || log === void 0 ? void 0 : log.warn(`#### ${lastevent.agentStatus}`);
799
+ log === null || log === void 0 ? void 0 : log.warn('last event:', lastevent);
800
+ log === null || log === void 0 ? void 0 : log.error(`Agent execution failed: ${JSON.stringify(lastevent)}`);
801
+ log === null || log === void 0 ? void 0 : log.done(' Agent execution failed ');
802
+ }
803
+ processedEvents++;
804
+ }
805
+ } while ((lastevent === null || lastevent === void 0 ? void 0 : lastevent.agentStatus) !== "failed" && (lastevent === null || lastevent === void 0 ? void 0 : lastevent.agentStatus) !== "completed");
806
+ if ((lastevent === null || lastevent === void 0 ? void 0 : lastevent.agentStatus) === "failed") {
807
+ const failureUpdate = {
808
+ kind: 'status-update',
809
+ taskId: taskId,
810
+ contextId: contextId,
811
+ status: {
812
+ state: 'failed',
813
+ message: {
814
+ kind: 'message',
815
+ role: 'agent',
816
+ messageId: (0, uuid_1.v4)(),
817
+ parts: [{ kind: 'text', text: `Agent execution failed: ${(lastevent === null || lastevent === void 0 ? void 0 : lastevent.message) || ''}` }],
818
+ taskId: taskId,
819
+ contextId: contextId,
820
+ },
821
+ timestamp: new Date().toISOString(),
822
+ },
823
+ final: true,
824
+ };
825
+ eventBus.publish(failureUpdate);
826
+ }
827
+ else if ((lastevent === null || lastevent === void 0 ? void 0 : lastevent.agentStatus) === "completed") {
828
+ const completedUpdate = {
829
+ kind: 'status-update',
830
+ taskId: taskId,
831
+ contextId: contextId,
832
+ status: {
833
+ state: 'completed',
834
+ message: {
835
+ kind: 'message',
836
+ role: 'agent',
837
+ messageId: (0, uuid_1.v4)(),
838
+ parts: [{ kind: 'text', text: lastevent.output.response }],
839
+ taskId: taskId,
840
+ contextId: contextId,
841
+ },
842
+ timestamp: new Date().toISOString(),
843
+ },
844
+ final: true,
845
+ };
846
+ eventBus.publish(completedUpdate);
847
+ }
848
+ return;
849
+ }
850
+ catch (error) {
851
+ log === null || log === void 0 ? void 0 : log.error(`[${this.Name}:AgentExecutor] Error processing task ${taskId}:`, error);
852
+ const errorUpdate = {
853
+ kind: 'status-update',
854
+ taskId: taskId,
855
+ contextId: contextId,
856
+ status: {
857
+ state: 'failed',
858
+ message: {
859
+ kind: 'message',
860
+ role: 'agent',
861
+ messageId: (0, uuid_1.v4)(),
862
+ parts: [{ kind: 'text', text: `Error processing your message: ${error instanceof Error ? error.message : String(error)}` }],
863
+ taskId: taskId,
864
+ contextId: contextId,
865
+ },
866
+ timestamp: new Date().toISOString(),
867
+ },
868
+ final: true,
869
+ };
870
+ eventBus.publish(errorUpdate);
871
+ }
872
+ }
873
+ // Function to get the host IP address
874
+ getHostIPAddress() {
875
+ const interfaces = node_os_1.default.networkInterfaces();
876
+ for (const interfaceName in interfaces) {
877
+ for (const interfaceInfo of interfaces[interfaceName] || []) {
878
+ if (interfaceInfo.family === 'IPv4' && !interfaceInfo.internal) {
879
+ return interfaceInfo.address;
880
+ }
881
+ }
882
+ }
883
+ return 'localhost';
884
+ }
885
+ /**
886
+ * Port for A2A express server
887
+ * @returns Port number from config or default 41241
888
+ */
889
+ getPort() {
890
+ return this.config.port || 41241;
891
+ }
892
+ /**
893
+ * get A2A express server app
894
+ * @param taskStore Optional TaskStore, defaults to InMemoryTaskStore
895
+ * @returns A2A Express app
896
+ */
897
+ getA2AServer(taskStore = new server_1.InMemoryTaskStore()) {
898
+ // Set up the server.
899
+ const requestHandler = new server_1.DefaultRequestHandler(this.getAgentCard(), taskStore, this);
900
+ const appBuilder = new express_1.A2AExpressApp(requestHandler);
901
+ const expressApp = appBuilder.setupRoutes((0, express_2.default)());
902
+ return { app: expressApp, port: this.getPort() };
903
+ }
904
+ getAgentCard() {
905
+ return {
906
+ version: '0.0.1', // Incremented version
907
+ protocolVersion: '0.3.0',
908
+ name: this.Name,
909
+ description: this.Description,
910
+ // Adjust the base URL and port in A2AExpressApp
911
+ url: `http://${this.getHostIPAddress()}:${this.getPort()}/`,
912
+ provider: {
913
+ organization: 'PS',
914
+ url: 'https://example.com/a2a-agent' // Added provider URL
915
+ },
916
+ capabilities: {
917
+ streaming: true, // The new framework supports streaming
918
+ pushNotifications: false, // Assuming not implemented for this agent yet
919
+ stateTransitionHistory: true, // Agent uses history
920
+ },
921
+ // authentication: null, // Property 'authentication' does not exist on type 'AgentCard'.
922
+ securitySchemes: undefined, // Or define actual security schemes if any
923
+ security: undefined,
924
+ defaultInputModes: ['text'],
925
+ defaultOutputModes: ['text', 'task-status'], // task-status is a common output mode
926
+ skills: [
927
+ {
928
+ id: this.Name.toLowerCase().replace(/\s+/g, '-'),
929
+ name: this.Name,
930
+ description: this.Description,
931
+ tags: ['psagent'],
932
+ examples: this.config.examples || [],
933
+ inputModes: ['text'], // Explicitly defining for skill
934
+ outputModes: ['text', 'task-status'] // Explicitly defining for skill
935
+ },
936
+ ...this.tasks.map(task => ({
937
+ id: task.Name.toLowerCase().replace(/\s+/g, '-'),
938
+ name: task.Name,
939
+ description: task.Description,
940
+ tags: ['psagent-task'],
941
+ examples: task.Examples,
942
+ inputModes: ['text'], // Assuming text input for tasks
943
+ outputModes: ['text', 'task-status'] // Assuming text and status output for tasks
944
+ }))
945
+ ],
946
+ supportsAuthenticatedExtendedCard: false,
947
+ };
948
+ }
949
+ static FromConfigFile(config_path) {
950
+ if (!node_fs_1.default.existsSync(config_path)) {
951
+ throw new Error(`Config file ${config_path} does not exist`);
952
+ }
953
+ const ext = node_path_1.default.extname(config_path).toLowerCase();
954
+ let configData;
955
+ if (ext === '.json') {
956
+ const fileContent = node_fs_1.default.readFileSync(config_path, 'utf-8');
957
+ configData = JSON.parse(fileContent);
958
+ }
959
+ else if (ext === '.yaml' || ext === '.yml') {
960
+ const fileContent = node_fs_1.default.readFileSync(config_path, 'utf-8');
961
+ configData = yaml_1.default.parse(fileContent);
962
+ }
963
+ else {
964
+ throw new Error('Unsupported config file format. Use JSON or YAML.');
965
+ }
966
+ // Basic validation of required fields
967
+ const requiredFields = ['name', 'description', 'instruction'];
968
+ for (const field of requiredFields) {
969
+ if (!configData[field]) {
970
+ throw new Error(`Missing required field '${field}' in config file.`);
971
+ }
972
+ }
973
+ // Convert tools and tasks if present
974
+ if (configData.tools && Array.isArray(configData.tools)) {
975
+ configData.tools = configData.tools.map((toolConfig) => new PSAgentTool_1.PSAgentTool(toolConfig));
976
+ }
977
+ else {
978
+ configData.tools = [];
979
+ }
980
+ if (configData.tasks && Array.isArray(configData.tasks)) {
981
+ configData.tasks = configData.tasks.map((taskConfig) => new PSAgentTask_1.PSAgentTask(taskConfig.name, taskConfig.description));
982
+ }
983
+ else {
984
+ configData.tasks = [];
985
+ }
986
+ return new PSAgent(configData);
987
+ }
988
+ }
989
+ exports.PSAgent = PSAgent;
990
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNBZ2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvUFNBZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFtQ0Esc0JBRUM7QUFyQ0QsdURBQXVEO0FBQ3ZELHNEQUF5QjtBQUN6QixzREFBeUI7QUFDekIsMERBQTZCO0FBUTdCLCtDQU80QjtBQUM1Qix3REFBMkQ7QUFDM0Qsc0RBQThCO0FBQzlCLDhEQUFxQztBQUNyQywrQkFBb0MsQ0FBQyw0QkFBNEI7QUFDakUsZ0RBQXdCO0FBQ3hCLCtCQUEyQjtBQUUzQixpQ0FBOEI7QUFHOUIsK0NBQTRDO0FBQzVDLCtDQUFnRTtBQUVoRSx1RUFBdUU7QUFDdkUsTUFBTSxLQUFLLEdBQUcsSUFBQSxxQkFBVSxFQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUVoQyxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDcEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMENHO0FBQ0gsTUFBYSxPQUFPO0lBa0JsQjs7O09BR0c7SUFDSCxZQUFZLE1BQTBDO1FBcEI5QyxVQUFLLEdBQWdCLEVBQUUsQ0FBQztRQUN4QixVQUFLLEdBQWdCLEVBQUUsQ0FBQztRQUt4QixtQkFBYyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFFcEMsZUFBVSxHQUFHLEtBQUssRUFDbkIsTUFBYyxFQUVELEVBQUU7WUFDakIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaEMsaUVBQWlFO1FBQ3JFLENBQUMsQ0FBQztRQU9BLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxHQUFH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