Agents
Overview#
Use the Agents API to list, create, update, retrieve, and delete agents. You can also use it to upload and retrieve source code for agents.
With this REST API, you can do the following:
- List agents
- Create agent
- Get agent by ID
- Update agent by ID
- Delete agent by ID
- Upload agent source code
- Get agent source code
List agents#
Endpoints#
GET aisvc/api/v1/agentsRequest#
Query parameters#
| Parameter | Type | Description | Required |
|---|---|---|---|
_offset | Number | Number of results to skip | Optional |
_pageSize | Number | Number of results per page | Optional |
_userType | String | Filter by the agent's unique _userType identifier | Optional |
_type | String | Filter by the agent type, such as user_agent or system_agent | Optional |
query | String | Wildcard search on the name, description, and background of agents | Optional |
Request example#
None
Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
{ "_offset": 0, "_pageSize": 1, "_total": 50, "_list": [ { "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ], "_id": "6fe848f8-3d9b-48ff-bcf1-643756168904", "_irn": "aisvc:agent:6fe848f8-3d9b-48ff-bcf1-643756168904", "_metadata": { "_createdAt": "1757048208583", "_updatedById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_createdById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_updatedAt": "1757048208583" } } ]}Create agent#
Endpoints#
POST aisvc/api/v1/agentsRequest#
Request body#
| Parameter | Type | Description | Required |
|---|---|---|---|
_namespaces | Array of String | One or more namespaces that contain the resource | Required |
_name | String | The agent's name | Required |
_background | String | Enter a promp for prompt engineering. | Required |
_userType | String | Unique identifier of the agent | Required |
_description | String | Agent's description | Optional |
_tools | Array of String | The identifiers (_userType) of tools that the agent uses | Optional |
_knowledgebases | Array of String | The identifiers (_userType) of knowledge bases the agent uses | Optional |
_agentClass | String | Class name of the custom agent implementation | Optional |
_config | Object | The agent's LLM model configuration. See additional _config properties below. | Required |
_config._model | Object | The agent's LLM model. Currently, it supports the following OpenAI models: gpt-4o, o4-mini, o3, o3-mini, o1, gpt-4.1, chatgpt-4o-latest, gpt-4.1-nano, gpt-4o-mini, gpt-3.5-turbo, gpt-4-turbo, gpt-4, gpt-5, gpt-5-mini, gpt-5-nano, gpt-5-chat-latest. | Required |
_config._provider | Object | The provider of the agent's LLM model. Currently only openai is supported. | Required |
Request body example#
[ { "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ] }]Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
{ "_offset": 0, "_pageSize": 1, "_total": 1, "_list": [ { "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ], "_id": "6fe848f8-3d9b-48ff-bcf1-643756168904", "_irn": "aisvc:agent:6fe848f8-3d9b-48ff-bcf1-643756168904", "_metadata": { "_createdAt": "1757048208583", "_updatedById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_createdById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_updatedAt": "1757048208583" } } ]}Get agent by ID#
Endpoints#
GET aisvc/api/v1/agents/{id}Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
{ "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ], "_id": "6fe848f8-3d9b-48ff-bcf1-643756168904", "_irn": "aisvc:agent:6fe848f8-3d9b-48ff-bcf1-643756168904", "_metadata": { "_createdAt": "1757048208583", "_updatedById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_createdById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_updatedAt": "1757048208583" } }Update agent by ID#
Endpoints#
PUT aisvc/api/v1/agents/{id}Request#
Request body#
| Parameter | Type | Description | Required |
|---|---|---|---|
_name | String | The agent name | Required |
_background | String | The context for the agent | Required |
_userType | String | Unique identifier of the agent | Required |
_description | String | Agent's description | Optional |
_tools | Array of String | The identifiers (_userType) of tools usable by the agent | Optional |
_knowledgebases | Array of String | The identifiers (_userType) of knowledge bases usable by agent | Optional |
_agentClass | String | Class name of the custom agent implementation | Optional |
_config | Object | Configuration for the agent's LLM model | Required |
Request body example#
{ "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ]}Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
{ "_name": "Related Query Helper Agent", "_background": "It interacts with Related Query Tool to generate related queries as JSON based on user prompt and provide this as input to the SearchRelatedItemsTool to retrive data from Item service", "_userType": "related_query_helper_agent", "_namespaces": [ "iputGraph_kxYOcW7O" ], "_config": { "_model": "gpt-4o", "_provider": "openai" }, "_tools": [ "RelatedQueryTool", "SearchRelatedItemsTool" ], "_id": "6fe848f8-3d9b-48ff-bcf1-643756168904", "_irn": "aisvc:agent:6fe848f8-3d9b-48ff-bcf1-643756168904", "_metadata": { "_createdAt": "1757048208583", "_updatedById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_createdById": "70699091-77de-4ee3-8a3f-034ec8746a3b", "_updatedAt": "1757048208583" } }Delete agent by ID#
Endpoints#
DELETE aisvc/api/v1/agents/{id}Request#
Request body#
None
Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
// empty response bodyUpload Agent Source Code#
Endpoints#
PUT aisvc/api/v1/agents/{id}/sourcecodesRequest#
Request body#
{ "_content":"import { Agent } from '@dtplatform/agent-core';\nimport { IafItemSvc } from '@dtplatform/platform-api';\n\ninterface ChillerRequest {\n chillerId: string;\n capacityKw: number;\n metric: string; // e.g. \"chiller_load_kw\"\n thresholdPct: number; // e.g. 0.9 for 90%\n lookbackDays?: number;\n}\n\ntype Reading = {\n _id: string;\n _ts: string; // timestamp in UTC\n chiller_load_kw: number;\n chiller_load_pct: number;\n};\n\ntype Data = {\n _list: Reading[];\n};\n\nexport default class ChillerForecastAgent extends Agent {\n requestContext: any = {}\n constructor(options: any, requestContext: any) {\n super(options);\n this.requestContext = requestContext;\n }\n\n async processRequest(\n type: string,\n state?: any,\n prompt?: string,\n tools?: any[],\n userId?: string,\n sessionId?: string,\n chatHistory?: [],\n additionalParams?: Record<string, string>,\n ): Promise<any> {\n\n // ------------------------------\n // 1. Interpret prompt (simple parsing via LLM)\n // ------------------------------\n const llmRes: any = await this.simpleCall(`Extract structured JSON from the following prompt. \n Fields: chillerId and lookbackDays (optional).\n Prompt: ${prompt}`);\n\n //console.log(llmRes, \">>llmRes\")\n console.log(llmRes?.content, \">>llmRes?.content\")\n\n let chillerReq: ChillerRequest;\n\n try {\n let rawContent: string = llmRes?.content || \"\";\n\n // Remove Markdown code fences if they exist\n rawContent = rawContent.replace(/```json|```/gi, \"\").trim();\n\n // Try to extract JSON block if extra text is present\n const jsonMatch = rawContent.match(/\{[\s\S]*\}/);\n if (jsonMatch) {\n rawContent = jsonMatch[0];\n }\n\n chillerReq = JSON.parse(rawContent);\n\n } catch (err) {\n console.error(\"Failed to parse chiller request:\", err);\n return {\n messages: [\n {\n role: \"assistant\",\n content: JSON.stringify({ error: \"Invalid LLM JSON response\", raw: llmRes })\n }\n ]\n };\n }\n\n const lookback = chillerReq.lookbackDays ?? 90;\n const startDate = new Date();\n startDate.setDate(startDate.getDate() - lookback);\n\n const aggs = [\n {\n $match: {\n \"_tsMetadata._sourceId\": { \"$regex\": `.*${chillerReq.chillerId}.*` } ,\n \"_ts\": { $gte: startDate.toISOString() }\n }\n },\n { $sort: { ts: 1 } },\n { $limit: 10 }\n\n ];\n\n console.log('Aggs::', JSON.stringify(aggs))\n \n let res = await IafItemSvc.aggregateReadings('68c50a58993fee0ea750db6f', aggs, this.requestContext, {});\n let finalRes = this.predictChiller90(res);\n console.log(finalRes, 'finalRes')\n return {\n messages: [\n {\n role: \"assistant\",\n content: `Chiller will cross 90% load around:\", ${finalRes}`\n }\n ]\n };\n }\n\n\n predictChiller90(data: Data): Date | null {\n // Step 1: clean duplicates by unique timestamp\n const readings: Reading[] = Object.values(\n data._list.reduce<Record<string, Reading>>((acc, item) => {\n acc[item._ts] = item; // overwrite duplicates\n return acc;\n }, {})\n );\n\n if (readings.length < 2) return null; // not enough data to predict\n\n // Step 2: sort by timestamp\n readings.sort((a, b) => new Date(a._ts).getTime() - new Date(b._ts).getTime());\n\n // Step 3: convert timestamps to epoch ms\n const points = readings.map(r => ({\n ts: new Date(r._ts).getTime(),\n load: r.chiller_load_pct\n }));\n\n // Step 4: calculate slope & intercept (linear regression)\n const n = points.length;\n const sumX = points.reduce((s, p) => s + p.ts, 0);\n const sumY = points.reduce((s, p) => s + p.load, 0);\n const sumXY = points.reduce((s, p) => s + p.ts * p.load, 0);\n const sumX2 = points.reduce((s, p) => s + p.ts * p.ts, 0);\n\n const denominator = n * sumX2 - sumX * sumX;\n if (denominator === 0) return null; // avoid division by zero\n\n const slope = (n * sumXY - sumX * sumY) / denominator;\n const intercept = (sumY - slope * sumX) / n;\n\n // Step 5: solve for timestamp when load = 0.9\n const targetLoad = 0.9;\n const targetTs = (targetLoad - intercept) / slope;\n\n if (isNaN(targetTs) || !isFinite(targetTs)) return null;\n\n return new Date(targetTs);\n }\n\n}\n"}Response#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Get Agent Source Code#
Endpoints#
GET aisvc/api/v1/agents/{id}/sourcecodesResponse#
Codes#
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request |
404 | Not Found |
Response body#
[ { "_content": "import { Agent } from '@dtplatform/agent-core';\nimport { IafItemSvc } from '@dtplatform/platform-api';\n\ninterface ChillerRequest {\n chillerId: string;\n capacityKw: number;\n metric: string; // e.g. \"chiller_load_kw\"\n thresholdPct: number; // e.g. 0.9 for 90%\n lookbackDays?: number;\n}\n\ntype Reading = {\n _id: string;\n _ts: string; // timestamp in UTC\n chiller_load_kw: number;\n chiller_load_pct: number;\n};\n\ntype Data = {\n _list: Reading[];\n};\n\nexport default class ChillerForecastAgent extends Agent {\n requestContext: any = {}\n constructor(options: any, requestContext: any) {\n super(options);\n this.requestContext = requestContext;\n }\n\n async processRequest(\n type: string,\n state?: any,\n prompt?: string,\n tools?: any[],\n userId?: string,\n sessionId?: string,\n chatHistory?: [],\n additionalParams?: Record<string, string>,\n ): Promise<any> {\n \n\n // ------------------------------\n // 1. Interpret prompt (simple parsing via LLM)\n // ------------------------------\n const llmRes: any = await this.simpleCall(`Extract structured JSON from the following prompt. \n Fields: chillerId and lookbackDays (optional).\n Prompt: ${prompt}`);\n\n //console.log(llmRes, \">>llmRes\")\n console.log(llmRes?.content, \">>llmRes?.content\")\n\n let chillerReq: ChillerRequest;\n\n try {\n let rawContent: string = llmRes?.content || \"\";\n\n // Remove Markdown code fences if they exist\n rawContent = rawContent.replace(/```json|```/gi, \"\").trim();\n\n // Try to extract JSON block if extra text is present\n const jsonMatch = rawContent.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n rawContent = jsonMatch[0];\n }\n\n chillerReq = JSON.parse(rawContent);\n\n } catch (err) {\n console.error(\"Failed to parse chiller request:\", err);\n return {\n messages: [\n {\n role: \"assistant\",\n content: JSON.stringify({ error: \"Invalid LLM JSON response\", raw: llmRes })\n }\n ]\n };\n }\n\n // ------------------------------\n // 2. Query Related Items\n // ------------------------------\n const telItems = await IafItemSvc.getRelatedItems(\n '68c50a58993fee0ea750db6f',\n { query: { \"_sourceId\": { \"$regex\": `.*${chillerReq.chillerId}.*` } } },\n this.requestContext\n );\n\n const lookback = chillerReq.lookbackDays ?? 90;\n const startDate = new Date();\n startDate.setDate(startDate.getDate() - lookback);\n\n const aggs = [\n {\n $match: {\n \"_tsMetadata._sourceId\": { \"$regex\": `.*${chillerReq.chillerId}.*` } ,\n \"_ts\": { $gte: startDate.toISOString() }\n }\n },\n { $sort: { ts: 1 } },\n { $limit: 10 }\n\n ];\n\n console.log('Aggs::', JSON.stringify(aggs))\n \n let res = await IafItemSvc.aggregateReadings('68c50a58993fee0ea750db6f', aggs, this.requestContext, {});\n let finalRes = this.predictChiller90(res);\n console.log(finalRes, 'finalRes')\n return {\n messages: [\n {\n role: \"assistant\",\n content: `Chiller will cross 90% load around:\", ${finalRes}`\n }\n ]\n };\n }\n\n\n predictChiller90(data: Data): Date | null {\n // Step 1: clean duplicates by unique timestamp\n const readings: Reading[] = Object.values(\n data._list.reduce<Record<string, Reading>>((acc, item) => {\n acc[item._ts] = item; // overwrite duplicates\n return acc;\n }, {})\n );\n\n if (readings.length < 2) return null; // not enough data to predict\n\n // Step 2: sort by timestamp\n readings.sort((a, b) => new Date(a._ts).getTime() - new Date(b._ts).getTime());\n\n // Step 3: convert timestamps to epoch ms\n const points = readings.map(r => ({\n ts: new Date(r._ts).getTime(),\n load: r.chiller_load_pct\n }));\n\n // Step 4: calculate slope & intercept (linear regression)\n const n = points.length;\n const sumX = points.reduce((s, p) => s + p.ts, 0);\n const sumY = points.reduce((s, p) => s + p.load, 0);\n const sumXY = points.reduce((s, p) => s + p.ts * p.load, 0);\n const sumX2 = points.reduce((s, p) => s + p.ts * p.ts, 0);\n\n const denominator = n * sumX2 - sumX * sumX;\n if (denominator === 0) return null; // avoid division by zero\n\n const slope = (n * sumXY - sumX * sumY) / denominator;\n const intercept = (sumY - slope * sumX) / n;\n\n // Step 5: solve for timestamp when load = 0.9\n const targetLoad = 0.9;\n const targetTs = (targetLoad - intercept) / slope;\n\n if (isNaN(targetTs) || !isFinite(targetTs)) return null;\n\n return new Date(targetTs);\n }\n\n}\n" }]