Testing Locally
Test your Trik before publishing to ensure it works correctly.
Build First
If using TypeScript, compile to JavaScript:
npm run build
# or
tscEnsure your entry.module path points to the compiled output:
{
"entry": {
"module": "./dist/graph.js",
"export": "default",
"runtime": "node"
}
}Manual Testing
Using the Gateway
Create a test script:
// test.ts
import { TrikGateway } from '@trikhub/gateway';
async function test() {
const gateway = new TrikGateway();
// Load your local trik
await gateway.loadTrik('./');
// Test search action
console.log('Testing search...');
const searchResult = await gateway.execute(
'yourname/my-trik',
'search',
{ topic: 'AI' }
);
console.log('Search result:', JSON.stringify(searchResult, null, 2));
// Test with session
if (searchResult.success && searchResult.sessionId) {
console.log('\nTesting details with session...');
const detailsResult = await gateway.execute(
'yourname/my-trik',
'details',
{ reference: 'the first one' },
{ sessionId: searchResult.sessionId }
);
console.log('Details result:', JSON.stringify(detailsResult, null, 2));
}
}
test().catch(console.error);Run it:
npx tsx test.tsUsing the Playground
The playgrounds provide an interactive environment:
- Navigate to the JS playground:
cd examples/js/local-playground
npm install- Add your trik to
.trikhub/config.json:
{
"triks": ["yourname/my-trik"]
}- Run interactive mode:
npm run devTest your trik in conversation:
You: Search for articles about machine learning
Assistant: I found 3 articles about AI.
You: Show me the first one
Assistant: [Article content displayed]Unit Tests
Write unit tests for your graph logic:
// graph.test.ts
import { describe, it, expect } from 'vitest';
import graph from './graph';
describe('article-search', () => {
describe('search action', () => {
it('returns success template with results', async () => {
const result = await graph.invoke({
action: 'search',
input: { topic: 'AI' }
});
expect(result.responseMode).toBe('template');
expect(result.agentData.template).toBe('success');
expect(result.agentData.count).toBeGreaterThan(0);
});
it('returns empty template for no results', async () => {
const result = await graph.invoke({
action: 'search',
input: { topic: 'nonexistent-topic-xyz' }
});
expect(result.responseMode).toBe('template');
expect(result.agentData.template).toBe('empty');
});
});
describe('details action', () => {
it('returns article via passthrough', async () => {
const result = await graph.invoke({
action: 'details',
input: { articleId: 'art-001' }
});
expect(result.responseMode).toBe('passthrough');
expect(result.userContent.contentType).toBe('article');
expect(result.userContent.content).toContain('Healthcare');
});
it('returns not_found for invalid ID', async () => {
const result = await graph.invoke({
action: 'details',
input: { articleId: 'invalid-id' }
});
expect(result.responseMode).toBe('template');
expect(result.agentData.template).toBe('not_found');
});
});
});Run tests:
npm test
# or
npx vitestSession Handling Tests
describe('session handling', () => {
it('resolves ordinal references', async () => {
const result = await graph.invoke({
action: 'details',
input: { reference: 'the second one' },
session: {
sessionId: 'test-session',
history: [{
action: 'search',
input: { topic: 'AI' },
agentData: {
template: 'success',
articleIds: ['art-001', 'art-002', 'art-003']
}
}]
}
});
expect(result.responseMode).toBe('passthrough');
expect(result.userContent.metadata.articleId).toBe('art-002');
});
});Integration Tests
Test with actual LangChain integration:
// integration.test.ts
import { describe, it, expect } from 'vitest';
import { TrikGateway } from '@trikhub/gateway';
import { createLangChainTools } from '@trikhub/gateway/langchain';
describe('LangChain integration', () => {
it('creates tools from trik', async () => {
const gateway = new TrikGateway();
await gateway.loadTrik('./');
const tools = createLangChainTools(gateway, {});
expect(tools.length).toBeGreaterThan(0);
expect(tools.some(t => t.name.includes('search'))).toBe(true);
});
it('executes tool and returns result', async () => {
const gateway = new TrikGateway();
await gateway.loadTrik('./');
const tools = createLangChainTools(gateway, {});
const searchTool = tools.find(t => t.name.includes('search'));
const result = await searchTool?.invoke({ topic: 'AI' });
const parsed = JSON.parse(result);
expect(parsed.success).toBe(true);
});
});Schema Validation
Test that outputs match your declared schemas:
import Ajv from 'ajv';
import manifest from './manifest.json';
const ajv = new Ajv();
describe('schema validation', () => {
it('search output matches agentDataSchema', async () => {
const result = await graph.invoke({
action: 'search',
input: { topic: 'AI' }
});
const validate = ajv.compile(manifest.actions.search.agentDataSchema);
const valid = validate(result.agentData);
expect(valid).toBe(true);
if (!valid) console.log(validate.errors);
});
});Testing Checklist
Before publishing, verify:
- All actions return valid responses
- Template mode returns correct
templatevalues - Passthrough mode returns required
contentTypeandcontent - Error cases return appropriate error templates
- Session handling works for multi-turn conversations
- Outputs match declared schemas
- No sensitive data leaks into
agentData
Debugging Tips
Enable Debug Logging
const { tools } = await loadLangChainTriks({
debug: true // Logs all tool calls and responses
});Check Gateway Output
const result = await gateway.execute('my-trik', 'search', { topic: 'AI' });
console.log('Full result:', JSON.stringify(result, null, 2));Inspect Session History
// In your graph.ts
export default {
async invoke({ action, input, session }) {
console.log('Session ID:', session?.sessionId);
console.log('History entries:', session?.history?.length);
console.log('History:', JSON.stringify(session?.history, null, 2));
// ...
}
}Next: Publish your trik to the registry.