@hashgraphonline/conversational-agent
Version:
Hashgraph Online conversational AI agent implementing HCS-10 communication, HCS-2 registries, and content inscription on Hedera. https://hol.org
221 lines (190 loc) ⢠7.14 kB
text/typescript
/**
* Simplified test script to verify that InscribeHashinalTool is wrapped with FormValidatingToolWrapper
*
* This script verifies the fix for isZodObjectLike detection in langchain-agent.ts
*
* Expected behavior:
* 1. InscribeHashinalTool should be detected as having extendZodSchema with render config
* 2. Tool should be wrapped with FormValidatingToolWrapper during initialization
* 3. Wrapper type should be confirmed in the tools array
*
* Run with: pnpm tsx src/scripts/test-inscribe-wrapper-verification.ts
*/
import dotenv from 'dotenv';
import { ConversationalAgent } from '../conversational-agent';
import { NetworkType } from '@hashgraphonline/standards-sdk';
dotenv.config();
interface WrapperTestResult {
success: boolean;
message: string;
details: {
toolFound: boolean;
isWrapped: boolean;
wrapperType?: string;
hasRenderConfig?: boolean;
toolsCount: number;
};
}
/**
* Validates that required environment variables are present
*/
function validateEnvironment(): { success: boolean; message: string } {
const required = [
'HEDERA_OPERATOR_ID',
'HEDERA_OPERATOR_KEY',
'OPENAI_API_KEY'
];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
return {
success: false,
message: `Missing required environment variables: ${missing.join(', ')}`
};
}
return {
success: true,
message: 'Environment validation passed'
};
}
/**
* Creates and initializes a conversational agent for testing
*/
async function createTestAgent(): Promise<ConversationalAgent> {
const options = {
accountId: process.env.HEDERA_OPERATOR_ID!,
privateKey: process.env.HEDERA_OPERATOR_KEY!,
network: (process.env.HEDERA_NETWORK as 'testnet' | 'mainnet') || 'testnet',
openAIApiKey: process.env.OPENAI_API_KEY!,
openAIModelName: 'gpt-4o-mini',
verbose: false,
disableLogging: true,
entityMemoryEnabled: false,
};
const agent = new ConversationalAgent(options);
await agent.initialize();
return agent;
}
/**
* Test that the InscribeHashinalTool is properly wrapped with FormValidatingToolWrapper
*/
async function testInscribeHashinalWrapper(agent: ConversationalAgent): Promise<WrapperTestResult> {
console.log('š Checking InscribeHashinalTool wrapper status...');
try {
const underlyingAgent = agent.getAgent();
const tools = (underlyingAgent as unknown as { tools: Array<{ name: string; constructor: { name: string }; schema?: { _renderConfig?: unknown } }> }).tools;
const toolsCount = tools.length;
console.log(`š Total tools loaded: ${toolsCount}`);
const inscribeHashinalTool = tools.find(t => t.name === 'inscribeHashinal');
if (!inscribeHashinalTool) {
return {
success: false,
message: 'InscribeHashinal tool not found in tools array',
details: {
toolFound: false,
isWrapped: false,
toolsCount
}
};
}
const toolType = inscribeHashinalTool.constructor.name;
const isFormValidatingWrapper = toolType === 'FormValidatingToolWrapper';
const hasRenderConfig = !!inscribeHashinalTool.schema?._renderConfig;
console.log('š§ InscribeHashinal tool analysis:', {
name: inscribeHashinalTool.name,
type: toolType,
isFormValidatingWrapper,
hasRenderConfig,
hasSchema: !!inscribeHashinalTool.schema
});
if (isFormValidatingWrapper) {
return {
success: true,
message: 'InscribeHashinalTool is properly wrapped with FormValidatingToolWrapper',
details: {
toolFound: true,
isWrapped: true,
wrapperType: toolType,
hasRenderConfig,
toolsCount
}
};
} else {
return {
success: false,
message: `InscribeHashinalTool is not wrapped. Tool type: ${toolType}`,
details: {
toolFound: true,
isWrapped: false,
wrapperType: toolType,
hasRenderConfig,
toolsCount
}
};
}
} catch (error) {
console.error('ā Error during wrapper test:', error);
return {
success: false,
message: `Error during wrapper test: ${error instanceof Error ? error.message : String(error)}`,
details: {
toolFound: false,
isWrapped: false,
toolsCount: 0
}
};
}
}
/**
* Main test execution function
*/
async function runTest(): Promise<void> {
console.log('š Starting InscribeHashinalTool wrapper verification test\n');
try {
console.log('š Step 1: Validating environment...');
const envResult = validateEnvironment();
if (!envResult.success) {
console.error('ā', envResult.message);
process.exit(1);
}
console.log('ā
', envResult.message, '\n');
console.log('š Step 2: Initializing conversational agent...');
const agent = await createTestAgent();
console.log('ā
Agent initialized successfully\n');
console.log('š Step 3: Testing InscribeHashinalTool wrapper...');
const wrapperResult = await testInscribeHashinalWrapper(agent);
if (wrapperResult.success) {
console.log('ā
', wrapperResult.message);
console.log('\nš Test Results:');
console.log(` Tool Found: ${wrapperResult.details.toolFound}`);
console.log(` Is Wrapped: ${wrapperResult.details.isWrapped}`);
console.log(` Wrapper Type: ${wrapperResult.details.wrapperType}`);
console.log(` Has Render Config: ${wrapperResult.details.hasRenderConfig}`);
console.log(` Total Tools: ${wrapperResult.details.toolsCount}`);
console.log('\nš SUCCESS: InscribeHashinalTool form generation fix is working!');
console.log('\nš What this means:');
console.log('ā
isZodObjectLike detection fixed for tools with extendZodSchema');
console.log('ā
InscribeHashinalTool properly wrapped with FormValidatingToolWrapper');
console.log('ā
Form will be generated when attributes field is missing');
console.log('ā
Users will get form UI instead of validation errors');
} else {
console.error('ā', wrapperResult.message);
console.log('\nš Test Results:');
console.log(` Tool Found: ${wrapperResult.details.toolFound}`);
console.log(` Is Wrapped: ${wrapperResult.details.isWrapped}`);
console.log(` Wrapper Type: ${wrapperResult.details.wrapperType || 'N/A'}`);
console.log(` Has Render Config: ${wrapperResult.details.hasRenderConfig || false}`);
console.log(` Total Tools: ${wrapperResult.details.toolsCount}`);
console.log('\nā FAILURE: Fix may not be working correctly');
process.exit(1);
}
await agent.cleanup();
} catch (error) {
console.error('ā Test failed with error:', error);
console.error('Error details:', error instanceof Error ? error.stack : String(error));
process.exit(1);
}
}
runTest().catch((error) => {
console.error('Unhandled test error:', error);
process.exit(1);
});