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,314 @@
1
+ // import { EmbeddingsInterface } from '@langchain/core/embeddings';
2
+ // fetch-retry can also wrap Node.js's native fetch API implementation:
3
+ const fetch = require('fetch-retry')(global.fetch);
4
+ import { JwtUtils } from './jwt';
5
+ import { PSAgentLogger } from './PSAgentLogger';
6
+ import express from 'express';
7
+ const log = new PSAgentLogger();
8
+ let existingToken = {
9
+ service_token: null,
10
+ refresh_token: null,
11
+ expires: new Date(0),
12
+ service_expires: new Date(0)
13
+ };
14
+ // export default class AIHelper implements EmbeddingsInterface{
15
+ export class PSAI {
16
+ token;
17
+ dimensions;
18
+ baseUrl;
19
+ log;
20
+ clientid;
21
+ constructor(token, baseUrl, log) {
22
+ this.token = token;
23
+ this.baseUrl = baseUrl || process.env.PS_API_URL || '';
24
+ this.clientid = process.env.PS_CLIENT_ID || '';
25
+ this.dimensions = 1536; // default to 1536 dimensions (for text-embedding-3-small)
26
+ this.log = log || new PSAgentLogger();
27
+ }
28
+ getDimensions(embeddingModel = 'text-embedding-3-small') {
29
+ if (embeddingModel === 'text-embedding-3-small') {
30
+ return 1536;
31
+ }
32
+ else if (embeddingModel === 'text-embedding-3-large') {
33
+ return 3072;
34
+ }
35
+ else if (embeddingModel === 'text-embedding-ada-002') {
36
+ return 1536;
37
+ }
38
+ else {
39
+ return this.dimensions;
40
+ }
41
+ }
42
+ async embedQuery(text, embeddingModel = 'text-embedding-3-small') {
43
+ const response = await fetch(`${this.baseUrl}/api/v1/vectors/embeddings`, {
44
+ method: 'POST',
45
+ headers: {
46
+ 'Content-Type': 'application/json',
47
+ 'Authorization': `Bearer ${this.token}`,
48
+ 'x-client-id': this.clientid || '',
49
+ },
50
+ body: JSON.stringify({
51
+ input: text,
52
+ model: embeddingModel,
53
+ "dimensions": this.getDimensions(embeddingModel),
54
+ }),
55
+ });
56
+ const data = await response.json();
57
+ if (!response.ok) {
58
+ this.log.error(`Failed to fetch embedding: ${response.status} ${response.statusText}`, data);
59
+ throw new Error(`HTTP error! status: ${response.status}`);
60
+ }
61
+ return data.data[0].embedding;
62
+ }
63
+ async embedDocuments(text, embeddingModel = 'text-embedding-3-small') {
64
+ const response = await fetch(`${this.baseUrl}/api/v1/vectors/embeddings`, {
65
+ method: 'POST',
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ 'Authorization': `Bearer ${this.token}`,
69
+ 'x-client-id': this.clientid || '',
70
+ },
71
+ body: JSON.stringify({
72
+ input: text,
73
+ model: embeddingModel,
74
+ "dimensions": this.getDimensions(embeddingModel),
75
+ }),
76
+ });
77
+ const data = await response.json();
78
+ if (!response.ok) {
79
+ this.log.error(`Failed to fetch embedding: ${response.status} ${response.statusText}`, data);
80
+ throw new Error(`HTTP error! status: ${response.status}`);
81
+ }
82
+ return data.data.map((item) => item.embedding);
83
+ }
84
+ async getModels() {
85
+ const lres = await fetch(`${this.baseUrl}/api/v1/llm/models`, {
86
+ headers: {
87
+ 'Authorization': `Bearer ${this.token}`,
88
+ }
89
+ });
90
+ if (!lres.ok) {
91
+ this.log.error(`Failed to fetch LLM models: ${lres.status} ${lres.statusText}`);
92
+ }
93
+ const { data: models } = await lres.json();
94
+ return models;
95
+ }
96
+ async llm(prompt, model = "o3-mini", systemmsg = "You are a helpful assistant. Answer as concisely as possible.") {
97
+ try {
98
+ const res = await fetch(`${this.baseUrl}/api/v1/llm/chat/completions`, {
99
+ method: "POST",
100
+ headers: {
101
+ "Content-Type": "application/json",
102
+ "Authorization": `Bearer ${this.token}`,
103
+ },
104
+ body: JSON.stringify({
105
+ model,
106
+ messages: [
107
+ { role: "system", content: systemmsg },
108
+ { role: "user", content: prompt }
109
+ ]
110
+ }),
111
+ retries: 3,
112
+ retryOn: function (attempt, error, response) {
113
+ // retry on any network error, or 4xx or 5xx status codes
114
+ if (error !== null || response.status >= 400 && attempt < 4) {
115
+ this.log.warn(`retrying execute agent, attempt number ${attempt + 1}`);
116
+ return true;
117
+ }
118
+ return false;
119
+ },
120
+ retryDelay: function (attempt, _error, _response) {
121
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
122
+ }
123
+ });
124
+ if (!res.ok) {
125
+ this.log.debug(`Failed to fetch LLM completion: ${res.status} ${res.statusText}`);
126
+ try {
127
+ const errorData = (await res.json());
128
+ this.log.debug(errorData);
129
+ throw new Error(`LLM call failed.\n\n status: ${res.status}, details: ${errorData}`);
130
+ }
131
+ catch (e) {
132
+ throw new Error(`LLM call failed.\n\n status: ${res.status}, and could not parse error response`);
133
+ }
134
+ }
135
+ const data = await res.json();
136
+ return data;
137
+ }
138
+ catch (error) {
139
+ this.log.debug('Error in llm call:', error);
140
+ throw error;
141
+ }
142
+ }
143
+ static async getServiceToken(options) {
144
+ const { baseurl = process.env.PS_API_URL || '', appkey = process.env.PS_SVC_APP_KEY || '', clientid = process.env.PS_SVC_CLIENT_ID || '', clientsecret = process.env.PS_SVC_CLIENT_SECRET || '' } = options || {};
145
+ if (!baseurl || !appkey || !clientid || !clientsecret) {
146
+ throw new Error('Missing required environment variables for service token retrieval');
147
+ }
148
+ const currentTime = new Date();
149
+ // Check if the existing token is still valid and expires after 20 minutes
150
+ if (existingToken && existingToken.service_token && existingToken.service_expires.getTime() > (currentTime.getTime() + 20 * 60000)) {
151
+ return existingToken.service_token;
152
+ }
153
+ const token = Buffer.from(`${clientid}:${clientsecret}`).toString('base64');
154
+ if (existingToken && existingToken.expires > currentTime) {
155
+ log.debug(`Found existing refresh token: ${existingToken.refresh_token}`);
156
+ const tres = await fetch(`${baseurl}/api/v2/auth/refreshtoken?client=machine`, {
157
+ headers: {
158
+ 'Authorization': `Basic ${token}`,
159
+ 'app-key': appkey || '',
160
+ 'rt': existingToken.refresh_token || ''
161
+ }
162
+ });
163
+ if (tres.ok) {
164
+ const { accessToken, refreshToken } = (await tres.json());
165
+ const spayload = JwtUtils.decode(accessToken);
166
+ const rpayload = JwtUtils.decode(refreshToken);
167
+ existingToken.service_token = accessToken;
168
+ existingToken.refresh_token = refreshToken;
169
+ existingToken.expires = new Date(rpayload?.exp * 1000);
170
+ existingToken.service_expires = new Date(spayload?.exp * 1000);
171
+ log.debug(`Refreshed service token: expires at ${existingToken.service_expires}`);
172
+ return accessToken;
173
+ }
174
+ else {
175
+ log.debug(`Failed to refresh service token, status: ${tres.status}`);
176
+ }
177
+ }
178
+ const tres = await fetch(`${baseurl}/api/v2/auth/login?client=machine&source=custom`, {
179
+ headers: {
180
+ 'Authorization': `Basic ${token}`,
181
+ 'app-key': appkey || ''
182
+ }
183
+ });
184
+ const { serviceToken, refreshToken } = (await tres.json());
185
+ const spayload = JwtUtils.decode(serviceToken);
186
+ const rpayload = JwtUtils.decode(refreshToken);
187
+ log.debug(`service token expires: ${JSON.stringify(new Date(spayload?.exp * 1000))}`);
188
+ log.debug(`refresh token expires: ${JSON.stringify(new Date(rpayload?.exp * 1000))}`);
189
+ existingToken.service_token = serviceToken;
190
+ existingToken.refresh_token = refreshToken;
191
+ existingToken.expires = new Date(rpayload?.exp * 1000);
192
+ existingToken.service_expires = new Date(spayload?.exp * 1000);
193
+ return serviceToken;
194
+ }
195
+ /**
196
+ * fetch access token by launching a local server to listen for the callback
197
+ * @param options - baseUrl and appKey for authentication
198
+ * @returns accessToken and refreshToken
199
+ * @throws error if any required values are missing or if authentication fails
200
+ */
201
+ static async getAuthToken(options) {
202
+ const { baseurl = options?.baseUrl || process.env.PS_API_URL || '', appkey = options?.appKey || process.env.PS_APP_KEY || '', } = options || {};
203
+ if (baseurl === '' || appkey === '') {
204
+ throw new Error('Missing required values baseUrl & appKey or default environment variables PS_API_URL/PS_APP_KEY for access token retrieval');
205
+ }
206
+ try {
207
+ let isCallbackFinished = false;
208
+ let callBackError = null;
209
+ let accessToken = null;
210
+ let refreshToken = null;
211
+ let appInitialized = false;
212
+ const app = express();
213
+ const router = express.Router();
214
+ router.use(express.json()); // for parsing application/json
215
+ router.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
216
+ router.get('/callback', (req, res) => {
217
+ const status = req.query.status;
218
+ if (status !== "success") {
219
+ log.error(`Authentication failed with status: ${status}`);
220
+ callBackError = `Authentication failed with status: ${status}`;
221
+ isCallbackFinished = true;
222
+ return res.status(400).send('Authentication failed');
223
+ }
224
+ log.debug("Authentication successful.");
225
+ accessToken = req.query["at"];
226
+ refreshToken = req.query["rt"];
227
+ if (!accessToken || !refreshToken) {
228
+ log.error('Missing access token or refresh token in callback');
229
+ callBackError = 'Missing access token or refresh token in callback';
230
+ isCallbackFinished = true;
231
+ return res.status(400).send('Missing tokens');
232
+ }
233
+ callBackError = null;
234
+ isCallbackFinished = true;
235
+ return res.status(200).send('Authentication successful! You can close this window.');
236
+ });
237
+ router.get('/login', async (_req, res) => {
238
+ const rurl = encodeURIComponent('http://localhost:3133/callback');
239
+ const loginUrl = `${baseurl}/api/v2/auth/login?client=desktop&redirect_url=${rurl}`;
240
+ const lres = await fetch(loginUrl, {
241
+ headers: { 'app-key': appkey || '' }
242
+ });
243
+ if (lres.status >= 400) {
244
+ log.error(`Failed to initiate login: ${lres.status} ${lres.statusText}`);
245
+ callBackError = `Failed to initiate login: ${lres.status} ${lres.statusText}`;
246
+ isCallbackFinished = true;
247
+ return res.status(500).send('Failed to initiate login');
248
+ }
249
+ const data = lres.body;
250
+ if (!data) {
251
+ log.error('No response body from login initiation');
252
+ callBackError = 'No response body from login initiation';
253
+ isCallbackFinished = true;
254
+ return res.status(500).send('No response body from login initiation');
255
+ }
256
+ const reader = data.getReader();
257
+ const decoder = new TextDecoder('utf-8');
258
+ let lresText = '';
259
+ while (true) {
260
+ const { done, value } = await reader.read();
261
+ if (done)
262
+ break;
263
+ lresText += decoder.decode(value);
264
+ }
265
+ if (!lresText || lresText.length === 0) {
266
+ log.error('Empty response body from login initiation');
267
+ callBackError = 'Empty response body from login initiation';
268
+ isCallbackFinished = true;
269
+ return res.status(500).send('Empty response body from login initiation');
270
+ }
271
+ log.debug('Redirecting to authentication provider');
272
+ return res.redirect(lresText);
273
+ });
274
+ app.use('', router);
275
+ app.listen(3133, () => {
276
+ log.debug('Listening on port 3133 for OAuth callback');
277
+ appInitialized = true;
278
+ }).on('error', (err) => {
279
+ log.error('Failed to start local server:', err);
280
+ callBackError = `Failed to start local server: ${err.message}`;
281
+ isCallbackFinished = true;
282
+ appInitialized = true;
283
+ });
284
+ do {
285
+ await new Promise(resolve => setTimeout(resolve, 500));
286
+ } while (!appInitialized && !callBackError);
287
+ if (appInitialized) {
288
+ console.log(`Please open the following URL in your browser to authenticate:\n\nhttp://localhost:3133/login\n`);
289
+ // Open the URL in the default browser
290
+ const open = (await import('open')).default;
291
+ await open(`http://localhost:3133/login`);
292
+ do {
293
+ await new Promise(resolve => setTimeout(resolve, 500));
294
+ } while (!isCallbackFinished && !callBackError);
295
+ }
296
+ if (callBackError) {
297
+ throw new Error(callBackError);
298
+ }
299
+ if (!accessToken || !refreshToken) {
300
+ throw new Error('Failed to obtain tokens from callback');
301
+ }
302
+ log.debug(`Obtained access token and refresh token from callback`);
303
+ return {
304
+ accessToken: accessToken,
305
+ refreshToken: refreshToken
306
+ };
307
+ }
308
+ catch (error) {
309
+ log.error('Error in getAccessToken:', error);
310
+ throw error;
311
+ }
312
+ }
313
+ }
314
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNBSS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvUFNBSS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxvRUFBb0U7QUFDcEUsdUVBQXVFO0FBQ3ZFLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBZ0IsTUFBTSxPQUFPLENBQUM7QUFDL0MsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sT0FBOEIsTUFBTSxTQUFTLENBQUM7QUFFckQsTUFBTSxHQUFHLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztBQUVoQyxJQUFJLGFBQWEsR0FLYjtJQUNGLGFBQWEsRUFBRSxJQUFJO0lBQ25CLGFBQWEsRUFBRSxJQUFJO0lBQ25CLE9BQU8sRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDcEIsZUFBZSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztDQUM3QixDQUFDO0FBRUYsZ0VBQWdFO0FBQ2hFLE1BQU0sT0FBTyxJQUFJO0lBQ0UsS0FBSyxDQUFTO0lBQ3ZCLFVBQVUsQ0FBUTtJQUNULE9BQU8sQ0FBUztJQUNoQixHQUFHLENBQWdCO0lBQ25CLFFBQVEsQ0FBUztJQUVsQyxZQUFZLEtBQWEsRUFBRSxPQUFnQixFQUFFLEdBQW1CO1FBQzlELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLDBEQUEwRDtRQUNsRixJ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
@@ -0,0 +1,215 @@
1
+ import { PSAgentConfig } from "./PSAgentConfig";
2
+ import { IPSAgentToolResult, PSAgentTool } from "./PSAgentTool";
3
+ import { PSAgentLogger } from "./PSAgentLogger";
4
+ import { z } from "zod/v4";
5
+ import { PSAgentTask } from "./PSAgentTask";
6
+ import type { AgentCard } from "@a2a-js/sdk";
7
+ import { AgentExecutor, RequestContext, ExecutionEventBus, TaskStore } from "@a2a-js/sdk/server";
8
+ import express from "express";
9
+ export declare function sleep(ms: number): Promise<void>;
10
+ /**
11
+ * PSAgent class to manage AI agents with tools and tasks
12
+ * Implements AgentExecutor interface from A2A SDK
13
+ * Supports starting, resuming, cancelling agents and executing tools
14
+ * Manages agent state, tools, tasks and interactions with A2A platform
15
+ * Includes methods for A2A server setup and event fetching
16
+ *
17
+ * uses the token from config if not PS_API_TOKEN env variable
18
+ * adds x-client-id, x-project-id, x-workspace-id from env variables
19
+ * PS_CLIENT_ID, PS_PROJECT_ID, PS_WORKSPACE_ID respectively for authentication headers
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { PSAI, PSAgent, PSAgentLogger } from 'psadk';
24
+ * import dotenv from 'dotenv';
25
+ * dotenv.config();
26
+ * async function main() {
27
+ * const token = await PSAI.getServiceToken({});
28
+ * const HelloAgent = new PSAgent({
29
+ * name: 'HelloAgent',
30
+ * description: 'A simple hello world agent',
31
+ * system_prompt: 'You are a helpful assistant that greets users.',
32
+ * model: 'gpt-5',
33
+ * tools: [],
34
+ * log: new PSAgentLogger({ level: 'info' }),
35
+ * token: token,
36
+ * port: 41241,
37
+ * });
38
+ * const { app, port } = HelloAgent.getServer();
39
+ * app.listen(port, () => {
40
+ * console.log('HelloAgent is running on http://localhost:${port}');
41
+ * });
42
+ * }
43
+ * main();
44
+ * ```
45
+ * @see PSAgentConfig, PSAgentTool, PSAgentTask
46
+ *
47
+ * @see
48
+ * https://dev.lionis.ai/docs/api/v1/agents/create-agent
49
+ * https://pscode.lioncloud.net/ai-tso/psadk_samples
50
+ * https://a2aproject.com/docs/getting-started/quickstart
51
+ *
52
+ */
53
+ export declare class PSAgent implements AgentExecutor {
54
+ config: PSAgentConfig;
55
+ private tools;
56
+ private tasks;
57
+ private agentId?;
58
+ private correlationId?;
59
+ private readonly log?;
60
+ private cancelledTasks;
61
+ cancelTask: (taskId: string, _eventBus: ExecutionEventBus) => Promise<void>;
62
+ /**
63
+ * create a new PSAgent with the given config
64
+ * @param config PSAgentConfig with optional logger
65
+ */
66
+ constructor(config: PSAgentConfig & {
67
+ log?: PSAgentLogger;
68
+ });
69
+ /**
70
+ * Get the Agent Class
71
+ * @returns Agent class from config or default "LlmAgent"
72
+ */
73
+ get AgentClass(): string;
74
+ /**
75
+ * Get the Name of the Agent
76
+ *
77
+ * @returns Name of the agent from config
78
+ */
79
+ get Name(): string;
80
+ /**
81
+ * Get the Description of the Agent
82
+ * @returns Description of the agent from config
83
+ */
84
+ get Description(): string;
85
+ /**
86
+ * Get the Instruction(System Prompt) of the Agent
87
+ * @returns Instruction(System prompt) of the agent from config
88
+ */
89
+ get Instruction(): string;
90
+ /**
91
+ * Get the Model of the Agent
92
+ * @returns Model of the agent from config
93
+ */
94
+ get Model(): string | undefined;
95
+ /**
96
+ * Get the Input Schema of the Agent
97
+ * @returns Input schema of the agent from config
98
+ */
99
+ get InputSchema(): z.core.JSONSchema.BaseSchema | undefined;
100
+ /**
101
+ * Get the Output Schema of the Agent
102
+ * @returns Output schema of the agent from config
103
+ */
104
+ get OutputSchema(): z.core.JSONSchema.BaseSchema | undefined;
105
+ /**
106
+ * Get the Token for the Agent
107
+ * @returns Token of the agent from config
108
+ */
109
+ get Token(): string | undefined;
110
+ /**
111
+ * Set the Token for the Agent
112
+ * @param value Token string to set in config
113
+ */
114
+ set Token(value: string | undefined);
115
+ /**
116
+ * Get the Tools for the Agent
117
+ * Includes both config tools and dynamically added tools
118
+ * @returns Array of PSAgentTool instances
119
+ */
120
+ get Tools(): PSAgentTool[];
121
+ /**
122
+ * Get the Tasks for the Agent
123
+ * Includes both config tasks and dynamically added tasks
124
+ * @returns Array of PSAgentTask instances
125
+ */
126
+ get Tasks(): PSAgentTask[];
127
+ /**
128
+ * Get the Agent ID after starting the agent
129
+ * @returns Agent ID string or undefined if not started
130
+ */
131
+ get AgentId(): string | undefined;
132
+ /**
133
+ * Get the Correlation ID after starting the agent
134
+ * @returns Correlation ID string or undefined if not started
135
+ */
136
+ get CorrelationId(): string | undefined;
137
+ /**
138
+ * Add tools to the agent dynamically
139
+ * @param tool PSAgentTool to add to the agent
140
+ */
141
+ addTool(tool: PSAgentTool): void;
142
+ private getToken;
143
+ private getAuthHeaders;
144
+ private getBaseUrl;
145
+ /**
146
+ * start a new temp agent on the agent platform
147
+ * @param input input to the agent the schema should match InputSchema if provided
148
+ * @param history history of messages for agent context
149
+ * @param log logger to use for logging, defaults to agent's logger
150
+ * @returns Correlation ID of the started agent
151
+ */
152
+ start(input: Object, history?: any[], log?: PSAgentLogger): Promise<string>;
153
+ /**
154
+ * resume the agent with tool output after a tool execution or human input
155
+ * @param tooloutput output from the tool execution to send back to the agent
156
+ * @returns
157
+ */
158
+ resume(tooloutput: Record<string, any>): Promise<Record<string, any>>;
159
+ /**
160
+ * deletes the agent running on the platform
161
+ * @param log optional logger to use for logging, defaults to agent's logger
162
+ */
163
+ cancel(log?: PSAgentLogger): Promise<void>;
164
+ /**
165
+ * Gets all the events for the current agent run identified correlation ID
166
+ * @returns Array of event objects for the current agent's correlation ID
167
+ * @see https://dev.lionis.ai/api/v1/events/events?correlationId={{correlation_id}}
168
+ */
169
+ getEvents(): Promise<Array<Record<string, any>>>;
170
+ /**
171
+ * Invoke the tool with the given name and input
172
+ * @remarks
173
+ * The input object should match the tool's input schema
174
+ *
175
+ * @param toolName name of the tool to execute
176
+ * @param input input object for the tool execution should match tool's input schema
177
+ * @param log logger to use for logging, defaults to agent's logger
178
+ * @returns output from the tool execution or error if any
179
+ *
180
+ * @example
181
+ * Example input for PSArtifactTool:
182
+ * ```json
183
+ * {
184
+ * "name": "example_artifact",
185
+ * "action": "write",
186
+ * "content": "This is an example artifact content."
187
+ * }
188
+ * ```
189
+ */
190
+ executeTool(toolName: string, input: Record<string, any>, log?: PSAgentLogger): Promise<IPSAgentToolResult>;
191
+ /**
192
+ *
193
+ * @param requestContext
194
+ * @param eventBus
195
+ * @returns
196
+ */
197
+ execute(requestContext: RequestContext, eventBus: ExecutionEventBus): Promise<void>;
198
+ private getHostIPAddress;
199
+ /**
200
+ * Port for A2A express server
201
+ * @returns Port number from config or default 41241
202
+ */
203
+ private getPort;
204
+ /**
205
+ *
206
+ * @param taskStore Optional TaskStore, defaults to InMemoryTaskStore
207
+ * @returns A2A Express app
208
+ */
209
+ getServer(taskStore?: TaskStore): {
210
+ app: express.Express;
211
+ port: number;
212
+ };
213
+ getAgentCard(): AgentCard;
214
+ static FromConfigFile(config_path: string): PSAgent;
215
+ }