matimo 0.1.0-alpha.2 → 0.1.0-alpha.3
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.
- package/README.md +80 -26
- package/dist/core/schema.d.ts +1 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +8 -3
- package/dist/core/schema.js.map +1 -1
- package/dist/core/tool-loader.d.ts.map +1 -1
- package/dist/core/tool-loader.js +15 -4
- package/dist/core/tool-loader.js.map +1 -1
- package/dist/core/tool-registry.d.ts.map +1 -1
- package/dist/core/tool-registry.js +5 -1
- package/dist/core/tool-registry.js.map +1 -1
- package/dist/decorators/tool-decorator.d.ts.map +1 -1
- package/dist/decorators/tool-decorator.js +7 -4
- package/dist/decorators/tool-decorator.js.map +1 -1
- package/dist/encodings/parameter-encoding.d.ts.map +1 -1
- package/dist/encodings/parameter-encoding.js +9 -2
- package/dist/encodings/parameter-encoding.js.map +1 -1
- package/dist/executors/command-executor.d.ts.map +1 -1
- package/dist/executors/command-executor.js +5 -1
- package/dist/executors/command-executor.js.map +1 -1
- package/dist/executors/http-executor.d.ts.map +1 -1
- package/dist/executors/http-executor.js +5 -1
- package/dist/executors/http-executor.js.map +1 -1
- package/package.json +4 -8
- package/tools/calculator/calculator.ts +78 -0
- package/tools/calculator/definition.yaml +71 -0
- package/tools/echo-tool/definition.yaml +35 -0
- package/tools/examples/calculator.yaml +54 -0
- package/tools/examples/echo-tool.yaml +35 -0
- package/tools/examples/http-client.yaml +66 -0
- package/tools/github/definition.yaml +41 -0
- package/tools/gmail/README.md +1189 -0
- package/tools/gmail/create-draft/definition.yaml +99 -0
- package/tools/gmail/definition.yaml +49 -0
- package/tools/gmail/delete-message/definition.yaml +42 -0
- package/tools/gmail/get-message/definition.yaml +89 -0
- package/tools/gmail/list-messages/definition.yaml +84 -0
- package/tools/gmail/send-email/definition.yaml +95 -0
- package/tools/http-client/definition.yaml +73 -0
- package/tools/slack/README.md +200 -0
- package/tools/slack/assets/icon.svg +9 -0
- package/tools/slack/assets/logo-dark.svg +14 -0
- package/tools/slack/assets/logo-light.svg +14 -0
- package/tools/slack/assets/logo.svg +14 -0
- package/tools/slack/definition.yaml +54 -0
- package/tools/slack/get-user/definition.yaml +31 -0
- package/tools/slack/list-channels/definition.yaml +46 -0
- package/tools/slack/send-message/definition.yaml +30 -0
- package/tools/slack/slack_add_reaction/definition.yaml +45 -0
- package/tools/slack/slack_create_channel/definition.yaml +41 -0
- package/tools/slack/slack_get_channel_history/definition.yaml +58 -0
- package/tools/slack/slack_get_reactions/definition.yaml +36 -0
- package/tools/slack/slack_get_thread_replies/definition.yaml +45 -0
- package/tools/slack/slack_get_user_info/definition.yaml +32 -0
- package/tools/slack/slack_join_channel/definition.yaml +35 -0
- package/tools/slack/slack_reply_to_message/definition.yaml +49 -0
- package/tools/slack/slack_search_messages/definition.yaml +46 -0
- package/tools/slack/slack_send_channel_message/definition.yaml +34 -0
- package/tools/slack/slack_send_dm/definition.yaml +37 -0
- package/tools/slack/slack_set_channel_topic/definition.yaml +40 -0
- package/tools/slack/slack_upload_file/definition.yaml +152 -0
- package/docs/Gemfile +0 -5
- package/docs/RELEASES.md +0 -90
- package/docs/ROADMAP.md +0 -138
- package/docs/_config.yml +0 -27
- package/docs/api-reference/ERRORS.md +0 -445
- package/docs/api-reference/SDK.md +0 -582
- package/docs/api-reference/TYPES.md +0 -415
- package/docs/architecture/OAUTH.md +0 -1366
- package/docs/architecture/OVERVIEW.md +0 -564
- package/docs/assets/logo.png +0 -0
- package/docs/community/COMMIT_GUIDELINES.md +0 -552
- package/docs/framework-integrations/LANGCHAIN.md +0 -286
- package/docs/getting-started/QUICK_START.md +0 -212
- package/docs/getting-started/YOUR_FIRST_TOOL.md +0 -217
- package/docs/getting-started/installation.md +0 -124
- package/docs/index.md +0 -289
- package/docs/tool-development/DECORATOR_GUIDE.md +0 -633
- package/docs/tool-development/OAUTH_LINK.md +0 -5
- package/docs/tool-development/PROVIDER_CONFIGURATION.md +0 -458
- package/docs/tool-development/TESTING.md +0 -412
- package/docs/tool-development/TOOL_SPECIFICATION.md +0 -793
- package/docs/tool-development/YAML_TOOLS.md +0 -65
- package/docs/troubleshooting/FAQ.md +0 -391
- package/docs/user-guide/AUTHENTICATION.md +0 -255
- package/docs/user-guide/DEVELOPMENT_STANDARDS.md +0 -698
- package/docs/user-guide/SDK_PATTERNS.md +0 -316
- package/docs/user-guide/TOOL_DISCOVERY.md +0 -209
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
# Testing Tools
|
|
2
|
-
|
|
3
|
-
Write and validate tests for Matimo tools.
|
|
4
|
-
|
|
5
|
-
## Tool Validation
|
|
6
|
-
|
|
7
|
-
### Validate All Tools
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Validate tool definitions (YAML syntax and schema)
|
|
11
|
-
pnpm validate-tools
|
|
12
|
-
|
|
13
|
-
# Output:
|
|
14
|
-
# ✅ tools/calculator/definition.yaml - Valid
|
|
15
|
-
# ✅ tools/gmail/send-email/definition.yaml - Valid
|
|
16
|
-
# ✅ tools/gmail/list-messages/definition.yaml - Valid
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
This validates:
|
|
20
|
-
- YAML syntax is correct
|
|
21
|
-
- All required fields present
|
|
22
|
-
- Parameter types are valid
|
|
23
|
-
- Execution config is complete
|
|
24
|
-
- Output schema is valid
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Unit Tests
|
|
29
|
-
|
|
30
|
-
### Test Tool Definition
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
import { describe, it, expect } from 'vitest';
|
|
34
|
-
import { ToolLoader } from 'matimo';
|
|
35
|
-
|
|
36
|
-
describe('Tool Definition', () => {
|
|
37
|
-
it('should load calculator tool', async () => {
|
|
38
|
-
const loader = new ToolLoader('./tools');
|
|
39
|
-
const tool = await loader.loadToolFromFile(
|
|
40
|
-
'./tools/calculator/definition.yaml'
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
expect(tool.name).toBe('calculator');
|
|
44
|
-
expect(tool.description).toBe('Perform basic math operations');
|
|
45
|
-
expect(tool.version).toBe('1.0.0');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should have required parameters', async () => {
|
|
49
|
-
const loader = new ToolLoader('./tools');
|
|
50
|
-
const tool = await loader.loadToolFromFile(
|
|
51
|
-
'./tools/calculator/definition.yaml'
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
expect(tool.parameters).toHaveProperty('operation');
|
|
55
|
-
expect(tool.parameters).toHaveProperty('a');
|
|
56
|
-
expect(tool.parameters).toHaveProperty('b');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should validate parameter types', async () => {
|
|
60
|
-
const loader = new ToolLoader('./tools');
|
|
61
|
-
const tool = await loader.loadToolFromFile(
|
|
62
|
-
'./tools/calculator/definition.yaml'
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
expect(tool.parameters!.operation.type).toBe('string');
|
|
66
|
-
expect(tool.parameters!.a.type).toBe('number');
|
|
67
|
-
expect(tool.parameters!.b.type).toBe('number');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should have execution config', async () => {
|
|
71
|
-
const loader = new ToolLoader('./tools');
|
|
72
|
-
const tool = await loader.loadToolFromFile(
|
|
73
|
-
'./tools/calculator/definition.yaml'
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
expect(tool.execution).toBeDefined();
|
|
77
|
-
expect(tool.execution.type).toMatch(/command|http/);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Integration Tests
|
|
85
|
-
|
|
86
|
-
### Test Tool Execution
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import { describe, it, expect, beforeAll } from 'vitest';
|
|
90
|
-
import { matimo } from 'matimo';
|
|
91
|
-
|
|
92
|
-
describe('Calculator Tool Execution', () => {
|
|
93
|
-
let m: Awaited<ReturnType<typeof matimo.init>>;
|
|
94
|
-
|
|
95
|
-
beforeAll(async () => {
|
|
96
|
-
m = await matimo.init('./tools');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should execute add operation', async () => {
|
|
100
|
-
const result = await m.execute('calculator', {
|
|
101
|
-
operation: 'add',
|
|
102
|
-
a: 5,
|
|
103
|
-
b: 3
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
expect(result.result).toBe(8);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('should execute subtract operation', async () => {
|
|
110
|
-
const result = await m.execute('calculator', {
|
|
111
|
-
operation: 'subtract',
|
|
112
|
-
a: 10,
|
|
113
|
-
b: 4
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
expect(result.result).toBe(6);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should execute multiply operation', async () => {
|
|
120
|
-
const result = await m.execute('calculator', {
|
|
121
|
-
operation: 'multiply',
|
|
122
|
-
a: 5,
|
|
123
|
-
b: 3
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
expect(result.result).toBe(15);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should execute divide operation', async () => {
|
|
130
|
-
const result = await m.execute('calculator', {
|
|
131
|
-
operation: 'divide',
|
|
132
|
-
a: 10,
|
|
133
|
-
b: 2
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
expect(result.result).toBe(5);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Parameter Validation Tests
|
|
144
|
-
|
|
145
|
-
### Test Parameter Constraints
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
import { describe, it, expect } from 'vitest';
|
|
149
|
-
import { matimo } from 'matimo';
|
|
150
|
-
|
|
151
|
-
describe('Calculator Parameter Validation', () => {
|
|
152
|
-
let m: Awaited<ReturnType<typeof matimo.init>>;
|
|
153
|
-
|
|
154
|
-
beforeAll(async () => {
|
|
155
|
-
m = await matimo.init('./tools');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should reject invalid operation', async () => {
|
|
159
|
-
expect(async () => {
|
|
160
|
-
await m.execute('calculator', {
|
|
161
|
-
operation: 'invalid', // Not in enum
|
|
162
|
-
a: 5,
|
|
163
|
-
b: 3
|
|
164
|
-
});
|
|
165
|
-
}).rejects.toThrow('INVALID_PARAMETERS');
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it('should require all parameters', async () => {
|
|
169
|
-
expect(async () => {
|
|
170
|
-
await m.execute('calculator', {
|
|
171
|
-
operation: 'add'
|
|
172
|
-
// Missing: a, b
|
|
173
|
-
});
|
|
174
|
-
}).rejects.toThrow('INVALID_PARAMETERS');
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('should validate parameter types', async () => {
|
|
178
|
-
expect(async () => {
|
|
179
|
-
await m.execute('calculator', {
|
|
180
|
-
operation: 'add',
|
|
181
|
-
a: 'five', // Should be number
|
|
182
|
-
b: 3
|
|
183
|
-
});
|
|
184
|
-
}).rejects.toThrow('INVALID_PARAMETERS');
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## OAuth2 Tool Tests
|
|
192
|
-
|
|
193
|
-
### Test OAuth2 Tools
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
import { describe, it, expect, beforeAll } from 'vitest';
|
|
197
|
-
import { matimo } from 'matimo';
|
|
198
|
-
|
|
199
|
-
describe('Gmail Tool Execution', () => {
|
|
200
|
-
let m: Awaited<ReturnType<typeof matimo.init>>;
|
|
201
|
-
|
|
202
|
-
beforeAll(async () => {
|
|
203
|
-
// Ensure GMAIL_ACCESS_TOKEN is set in environment
|
|
204
|
-
if (!process.env.GMAIL_ACCESS_TOKEN) {
|
|
205
|
-
console.warn('⚠️ Skipping Gmail tests: GMAIL_ACCESS_TOKEN not set');
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
m = await matimo.init('./tools');
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should send email', async () => {
|
|
213
|
-
if (!m) {
|
|
214
|
-
console.warn('Skipping: no Matimo instance');
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const result = await m.execute('gmail-send-email', {
|
|
219
|
-
to: 'test@example.com',
|
|
220
|
-
subject: 'Test Email',
|
|
221
|
-
body: 'This is a test email'
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
expect(result.messageId).toBeDefined();
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should list messages', async () => {
|
|
228
|
-
if (!m) return;
|
|
229
|
-
|
|
230
|
-
const result = await m.execute('gmail-list-messages', {
|
|
231
|
-
maxResults: 10
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
expect(result.messages).toBeDefined();
|
|
235
|
-
expect(Array.isArray(result.messages)).toBe(true);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('should handle missing auth token', async () => {
|
|
239
|
-
// Clear token temporarily
|
|
240
|
-
const saved = process.env.GMAIL_ACCESS_TOKEN;
|
|
241
|
-
delete process.env.GMAIL_ACCESS_TOKEN;
|
|
242
|
-
|
|
243
|
-
const m2 = await matimo.init('./tools');
|
|
244
|
-
|
|
245
|
-
expect(async () => {
|
|
246
|
-
await m2.execute('gmail-send-email', {
|
|
247
|
-
to: 'test@example.com',
|
|
248
|
-
subject: 'Test',
|
|
249
|
-
body: 'Test'
|
|
250
|
-
});
|
|
251
|
-
}).rejects.toThrow('AUTH_FAILED');
|
|
252
|
-
|
|
253
|
-
// Restore token
|
|
254
|
-
if (saved) {
|
|
255
|
-
process.env.GMAIL_ACCESS_TOKEN = saved;
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Error Handling Tests
|
|
264
|
-
|
|
265
|
-
### Test Error Conditions
|
|
266
|
-
|
|
267
|
-
```typescript
|
|
268
|
-
import { describe, it, expect } from 'vitest';
|
|
269
|
-
import { matimo } from 'matimo';
|
|
270
|
-
|
|
271
|
-
describe('Error Handling', () => {
|
|
272
|
-
let m: Awaited<ReturnType<typeof matimo.init>>;
|
|
273
|
-
|
|
274
|
-
beforeAll(async () => {
|
|
275
|
-
m = await matimo.init('./tools');
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it('should throw TOOL_NOT_FOUND', async () => {
|
|
279
|
-
expect(async () => {
|
|
280
|
-
await m.execute('unknown-tool', {});
|
|
281
|
-
}).rejects.toThrow('TOOL_NOT_FOUND');
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('should throw INVALID_PARAMETERS', async () => {
|
|
285
|
-
expect(async () => {
|
|
286
|
-
await m.execute('calculator', {
|
|
287
|
-
operation: 'add'
|
|
288
|
-
// Missing: a, b
|
|
289
|
-
});
|
|
290
|
-
}).rejects.toThrow('INVALID_PARAMETERS');
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it('should include error details', async () => {
|
|
294
|
-
try {
|
|
295
|
-
await m.execute('calculator', {
|
|
296
|
-
operation: 'invalid',
|
|
297
|
-
a: 5,
|
|
298
|
-
b: 3
|
|
299
|
-
});
|
|
300
|
-
expect.fail('Should throw error');
|
|
301
|
-
} catch (error) {
|
|
302
|
-
expect(error.code).toBe('INVALID_PARAMETERS');
|
|
303
|
-
expect(error.details).toBeDefined();
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
---
|
|
310
|
-
|
|
311
|
-
## Running Tests
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
# Run all tests
|
|
315
|
-
pnpm test
|
|
316
|
-
|
|
317
|
-
# Run with coverage
|
|
318
|
-
pnpm test:coverage
|
|
319
|
-
|
|
320
|
-
# Run in watch mode (during development)
|
|
321
|
-
pnpm test:watch
|
|
322
|
-
|
|
323
|
-
# Run specific test file
|
|
324
|
-
pnpm test -- tools.test.ts
|
|
325
|
-
|
|
326
|
-
# Run tests matching pattern
|
|
327
|
-
pnpm test -- --grep "Calculator"
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## Test Coverage
|
|
333
|
-
|
|
334
|
-
### View Coverage Report
|
|
335
|
-
|
|
336
|
-
```bash
|
|
337
|
-
pnpm test:coverage
|
|
338
|
-
|
|
339
|
-
# Output:
|
|
340
|
-
# ✅ 100% Statements
|
|
341
|
-
# ✅ 100% Branches
|
|
342
|
-
# ✅ 100% Functions
|
|
343
|
-
# ✅ 100% Lines
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## Best Practices
|
|
349
|
-
|
|
350
|
-
### 1. Test YAML Syntax First
|
|
351
|
-
|
|
352
|
-
Always validate YAML before testing execution:
|
|
353
|
-
|
|
354
|
-
```bash
|
|
355
|
-
pnpm validate-tools
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
### 2. Test Parameters Before Execution
|
|
359
|
-
|
|
360
|
-
```typescript
|
|
361
|
-
// First: validate tool definition
|
|
362
|
-
const tool = m.getTool('calculator');
|
|
363
|
-
expect(tool.parameters).toBeDefined();
|
|
364
|
-
|
|
365
|
-
// Then: test execution
|
|
366
|
-
const result = await m.execute('calculator', params);
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
### 3. Mock External Calls (for unit tests)
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
373
|
-
|
|
374
|
-
describe('Gmail Tool (Mocked)', () => {
|
|
375
|
-
it('should call Gmail API', async () => {
|
|
376
|
-
const mockExecute = vi.fn().mockResolvedValue({
|
|
377
|
-
messageId: 'msg_123'
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
const result = await mockExecute({
|
|
381
|
-
to: 'test@example.com',
|
|
382
|
-
subject: 'Test',
|
|
383
|
-
body: 'Test'
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
expect(result.messageId).toBe('msg_123');
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
### 4. Test Error Cases
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
it('should handle execution errors', async () => {
|
|
395
|
-
expect(async () => {
|
|
396
|
-
await m.execute('calculator', {
|
|
397
|
-
operation: 'divide',
|
|
398
|
-
a: 10,
|
|
399
|
-
b: 0 // Division by zero
|
|
400
|
-
});
|
|
401
|
-
}).rejects.toThrow();
|
|
402
|
-
});
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
## Next Steps
|
|
408
|
-
|
|
409
|
-
- **Tool Development**: [YAML Tool Specification](./YAML_TOOLS.md)
|
|
410
|
-
- **Error Codes**: [Error Reference](../api-reference/ERRORS.md)
|
|
411
|
-
- **Examples**: [Code Examples](../../examples/)
|
|
412
|
-
|