Custom tool
You can create your own tool on the platform and make API, RAG, and database calls from the tool.
Tool class object
{
"_name": "GetAssetsTool",
"_description": "The tool gets the asset based on the given criteria",
"_userType": "GetAssetsTool",
"_namespaces": ["Namespace_EleSnXBw"],
"_toolClass": "GetAssetsTool"
}
| Property | Type | Description |
|---|---|---|
_name | String | The tool name. The _name, _userType, and _toolClass properties should have the same value. |
_description | String | Enter a description for the tool. |
_userType | String | The _name, _userType, and _toolClass properties should have the same value. |
_toolClass | String | The class name in your tool script used to extend the abstract class. The _name, _userType, and _toolClass properties should have the same value. |
AbstractTool and Zod
AbstractTool
You can write custom tools by extending the AbstractTool class provided in the @dtplatform/agent-core platform library.
Zod
Use Zod, a schema validation library for TypeScript, to define the schema for the arguments that the tool's call methods receive.
Permissions
Only platform managers can upload script content to a custom tool. App developers must send script content to them for upload.
Language
Only TypeScript or JavaScript scripts are accepted.
Creating a custom tool
-
Create the tool resource using
IafAISvc.createTools:const tool = await IafAISvc.createTools([{"_name": "GetAssetsTool","_description": "The tool gets the asset based on the given criteria","_userType": "GetAssetsTool","_namespaces": ["Namespace_EleSnXBw"],"_toolClass": "GetAssetsTool"}]) -
Write the tool script content:
i. Import
AbstractTool,zod, and the platform APIs you require:import { AbstractTool } from '@dtplatform/agent-core';import { z } from 'zod';import * as PlatformAPI from '@dtplatform/platform-api';const { IafItemSvc } = PlatformAPI;ii. Define the schema for the Tool input parameters using zod:
const toolSchema = z.object({name: z.string().optional().nullable().describe('Filter by asset name. Supports regex'),dtCategory: z.string().optional().nullable().describe('Filter by the dtCategory property. Supports regex'),dtType: z.string().optional().nullable().describe('Filter by dtType property. Supports regex'),_pageSize: z.string().optional().nullable().describe('Sets the number of results to return per Page in the response'),_offset: z.string().optional().nullable().describe('Sets the number of results to skip in the Page response. For example, set to `10` to skip the first 10 results.')});iii. Create a your tool class that extends the AbstractTool class, then initialize the properties and schema:
export default class GetAssetsTool extends AbstractTool {name: string = 'GetAssetsTool';description: string = 'Helps to retrieve Assets based on the provided criteria.';requestContext: any = {};schema: any = toolSchema;constructor(...args: any[]) {super(...args);const [{ requestContext }] = args;this.requestContext = requestContext;}...}iv. Create a
_callmethod, which serves as a placeholder where you can place your API, RAG, or database calls. You can also add private class methods outside the_callmethod:...async _call(args: z.infer<typeof toolSchema>) {let criteria: any = { '$or': [] };let options: any = {};let response: any = {};if (args.name || args.dtCategory || args.dtType) {if (args.name) {criteria['$or'].push({'Asset Name': {'$regex': this.toRegexString(args.name),'$options': 'i'}});}if (args.dtCategory) {criteria['$or'].push({'properties.dtCategory.val': {'$regex': this.toRegexString(args.dtCategory),'$options': 'i'}});}if (args.dtType) {criteria['$or'].push({'properties.dtType.val': {'$regex': this.toRegexString(args.dtType),'$options': 'i'}});}if (args._pageSize) {options['_pageSize'] = parseInt(args._pageSize, 10);}if (args._offset) {options['_offset'] = parseInt(args._offset, 10);}let colQuery = {query: {_userType: 'iaf_ext_asset_coll',_itemClass: 'NamedUserCollection'}};const colOptions = {project: { _userType: 1, _itemClass: 1 },sort: { _name: 1 },page: { _offset: 0, _pageSize: 1 }};const colResponse = await IafItemSvc.getNamedUserItems(colQuery,this.requestContext,colOptions);let assetCollection: any = null;if (colResponse && Array.isArray(colResponse._list) && colResponse._list.length > 0) {assetCollection = colResponse._list[0];if (assetCollection && assetCollection._id) {response = await IafItemSvc.getRelatedItems(assetCollection._id,{query: criteria},this.requestContext,options);}}}return response;}//private class methodstoRegexString(str) {const quoted = str.match(/^'(.*)'$/);if (quoted) {const escaped = quoted[1].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');return `.*(${escaped}).*`;}const terms = str.split(/\s+/).map(term => term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));return `.*(${terms.join('|')}).*`;} -
The Platform Manager uploads the source code using
IafAISvc.uploadToolSourceCode://code as textawait IafAISvc.uploadToolSourceCode({"_content": "Your script goes here"});//or fileawait IafAISvc.uploadToolSourceCode({"_file": .ts file});