matimo-examples 0.1.0-alpha.11

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.
Files changed (57) hide show
  1. package/.env.example +49 -0
  2. package/LICENSE +21 -0
  3. package/README.md +525 -0
  4. package/agents/decorator-pattern-agent.ts +368 -0
  5. package/agents/factory-pattern-agent.ts +253 -0
  6. package/agents/langchain-agent.ts +146 -0
  7. package/edit/edit-decorator.ts +178 -0
  8. package/edit/edit-factory.ts +138 -0
  9. package/edit/edit-langchain.ts +292 -0
  10. package/execute/execute-decorator.ts +49 -0
  11. package/execute/execute-factory.ts +46 -0
  12. package/execute/execute-langchain.ts +232 -0
  13. package/github/github-decorator.ts +326 -0
  14. package/github/github-factory.ts +355 -0
  15. package/github/github-langchain.ts +206 -0
  16. package/github/github-with-approval.ts +228 -0
  17. package/gmail/README.md +345 -0
  18. package/gmail/gmail-decorator.ts +216 -0
  19. package/gmail/gmail-factory.ts +231 -0
  20. package/gmail/gmail-langchain.ts +201 -0
  21. package/hubspot/README.md +316 -0
  22. package/hubspot/hubspot-decorator.ts +180 -0
  23. package/hubspot/hubspot-factory.ts +188 -0
  24. package/hubspot/hubspot-langchain.ts +222 -0
  25. package/logger-example.ts +40 -0
  26. package/mailchimp/README.md +321 -0
  27. package/mailchimp/mailchimp-decorator.ts +277 -0
  28. package/mailchimp/mailchimp-factory.ts +187 -0
  29. package/mailchimp/mailchimp-langchain.ts +155 -0
  30. package/notion/README.md +293 -0
  31. package/notion/notion-decorator.ts +275 -0
  32. package/notion/notion-factory.ts +256 -0
  33. package/notion/notion-langchain.ts +237 -0
  34. package/package.json +79 -0
  35. package/postgres/README.md +188 -0
  36. package/postgres/postgres-decorator.ts +198 -0
  37. package/postgres/postgres-factory.ts +180 -0
  38. package/postgres/postgres-langchain.ts +213 -0
  39. package/postgres/postgres-with-approval.ts +344 -0
  40. package/read/read-decorator.ts +154 -0
  41. package/read/read-factory.ts +121 -0
  42. package/read/read-langchain.ts +273 -0
  43. package/search/search-decorator.ts +206 -0
  44. package/search/search-factory.ts +146 -0
  45. package/search/search-langchain.ts +255 -0
  46. package/slack/README.md +339 -0
  47. package/slack/slack-decorator.ts +245 -0
  48. package/slack/slack-factory.ts +226 -0
  49. package/slack/slack-langchain.ts +242 -0
  50. package/tsconfig.json +20 -0
  51. package/twilio/README.md +309 -0
  52. package/twilio/twilio-decorator.ts +288 -0
  53. package/twilio/twilio-factory.ts +238 -0
  54. package/twilio/twilio-langchain.ts +218 -0
  55. package/web/web-decorator.ts +52 -0
  56. package/web/web-factory.ts +70 -0
  57. package/web/web-langchain.ts +163 -0
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env node
2
+
3
+ import 'dotenv/config';
4
+ import { createAgent } from 'langchain';
5
+ import { ChatOpenAI } from '@langchain/openai';
6
+ import { MatimoInstance, convertToolsToLangChain, ToolDefinition } from '@matimo/core';
7
+
8
+ /**
9
+ * GitHub LangChain Agent Example - TRUE AI AGENT
10
+ * =============================================
11
+ *
12
+ * This is a **real autonomous AI agent** that:
13
+ * 1. Loads GitHub tools via Matimo
14
+ * 2. Converts them to LangChain tool schemas
15
+ * 3. Uses ChatOpenAI (gpt-4o-mini) to reason about requests
16
+ * 4. Autonomously calls GitHub APIs based on AI reasoning
17
+ * 5. Returns natural language responses to user queries
18
+ *
19
+ * This is NOT just a schema converter - it's a working AI agent!
20
+ *
21
+ * Setup:
22
+ * ------
23
+ * 1. GitHub Personal Access Token: https://github.com/settings/tokens
24
+ * export GITHUB_TOKEN="ghp_xxxx..."
25
+ *
26
+ * 2. OpenAI API Key: https://platform.openai.com/api-keys
27
+ * export OPENAI_API_KEY="sk-proj-..."
28
+ *
29
+ * 3. Run the agent:
30
+ * pnpm github:langchain
31
+ *
32
+ * Example User Requests (the AI will understand and execute):
33
+ * -----------------------------------------------------------
34
+ * - "Find popular TypeScript projects"
35
+ * - "What are the latest releases of Node.js?"
36
+ * - "Show me open issues in kubernetes/kubernetes"
37
+ * - "List contributors to the Go language repository"
38
+ * - "Search for async/await patterns in React source code"
39
+ *
40
+ * How it Works:
41
+ * ----------------------------
42
+ * 1. User provides natural language request
43
+ * 2. LLM (OpenAI) reads the GitHub tool definitions
44
+ * 3. LLM decides which tools to call and with what parameters
45
+ * 4. Matimo executes the selected GitHub APIs
46
+ * 5. Results returned to LLM for formatting
47
+ * 6. LLM provides natural language response to user
48
+ *
49
+ * This demonstrates true AI agent autonomy - the LLM decides
50
+ * WHAT tools to use and WHEN, not just executing predetermined actions.
51
+ */
52
+
53
+ interface AgentTask {
54
+ title: string;
55
+ description: string;
56
+ request: string;
57
+ }
58
+
59
+ async function main() {
60
+ console.info('\n╔════════════════════════════════════════════════════════════╗');
61
+ console.info('ā•‘ šŸ¤– GitHub AI Agent (True Autonomous Agent) ā•‘');
62
+ console.info('ā•‘ Powered by OpenAI + LangChain + Matimo ā•‘');
63
+ console.info('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n');
64
+
65
+ // Check required environment variables
66
+ const githubToken = process.env.GITHUB_TOKEN;
67
+ const openaiKey = process.env.OPENAI_API_KEY;
68
+
69
+ if (!githubToken) {
70
+ console.error('\nāŒ Error: GITHUB_TOKEN environment variable not set');
71
+ console.info(' Create token: https://github.com/settings/tokens');
72
+ console.info(' Set it: export GITHUB_TOKEN="ghp_xxxx..."\n');
73
+ process.exit(1);
74
+ }
75
+
76
+ if (!openaiKey) {
77
+ console.error('\nāŒ Error: OPENAI_API_KEY environment variable not set');
78
+ console.info(' Get key: https://platform.openai.com/api-keys');
79
+ console.info(' Set it: export OPENAI_API_KEY="sk-proj-..."\n');
80
+ process.exit(1);
81
+ }
82
+
83
+ try {
84
+ console.info('ā³ Initializing AI Agent...\n');
85
+
86
+ // Initialize Matimo
87
+ const matimo = await MatimoInstance.init({
88
+ autoDiscover: true,
89
+ });
90
+
91
+ // Get all GitHub tools
92
+ const allTools = matimo.listTools();
93
+ const githubTools = allTools.filter((t) => t.name.startsWith('github-'));
94
+ console.info(`āœ… Loaded ${githubTools.length} GitHub tools from Matimo\n`);
95
+
96
+ // Select safe read-only tools (no create/merge/delete)
97
+ const keyTools = githubTools.filter(
98
+ (t) =>
99
+ !t.name.includes('create-') &&
100
+ !t.name.includes('delete-') &&
101
+ !t.name.includes('update-') &&
102
+ !t.name.includes('merge-') &&
103
+ !t.name.includes('add-')
104
+ );
105
+
106
+ console.info(`šŸ“š Using ${keyTools.length} read-only tools (write operations excluded)\n`);
107
+
108
+ // Convert to LangChain tool format
109
+ console.info('šŸ”§ Converting tools to LangChain format...\n');
110
+ const langchainTools = await convertToolsToLangChain(keyTools as ToolDefinition[], matimo, {
111
+ GITHUB_TOKEN: githubToken,
112
+ });
113
+
114
+ // Initialize OpenAI LLM
115
+ console.info('šŸ¤– Initializing ChatOpenAI (gpt-4o-mini)...\n');
116
+ const model = new ChatOpenAI({
117
+ modelName: 'gpt-4o-mini',
118
+ temperature: 0.7,
119
+ apiKey: openaiKey,
120
+ });
121
+
122
+ // Create the agent
123
+ console.info('āš™ļø Creating autonomous agent...\n');
124
+ const agent = await createAgent({
125
+ model,
126
+ tools: langchainTools as any[],
127
+ });
128
+
129
+ // Define user tasks for the agent to complete
130
+ const userTasks: AgentTask[] = [
131
+ {
132
+ title: 'Search Popular Projects',
133
+ description: 'Find highly-starred TypeScript repositories',
134
+ request: 'Find the top TypeScript repositories with over 1000 stars',
135
+ },
136
+ {
137
+ title: 'Repository Intelligence',
138
+ description: 'Get details about a major open-source project',
139
+ request: 'Get detailed information about the kubernetes/kubernetes repository',
140
+ },
141
+ {
142
+ title: 'Project Activity',
143
+ description: 'Check recent development activity',
144
+ request:
145
+ 'List the 5 most recent commits to facebook/react and tell me what they were about',
146
+ },
147
+ {
148
+ title: 'Release Information',
149
+ description: 'Find latest releases of major projects',
150
+ request: 'What are the 3 most recent releases of golang/go?',
151
+ },
152
+ ];
153
+
154
+ console.info('🧪 Running GitHub AI Agent Tasks');
155
+ console.info('═'.repeat(60));
156
+
157
+ // Execute each task with the AI agent
158
+ for (const task of userTasks) {
159
+ console.info(`\n${task.title}`);
160
+ console.info('─'.repeat(60));
161
+ console.info(`ļæ½ User: "${task.request}"\n`);
162
+
163
+ try {
164
+ const response = await agent.invoke({
165
+ messages: [
166
+ {
167
+ role: 'user',
168
+ content: task.request,
169
+ },
170
+ ],
171
+ });
172
+
173
+ // Get the last message from the agent
174
+ const lastMessage = response.messages[response.messages.length - 1];
175
+ if (lastMessage) {
176
+ if (typeof lastMessage.content === 'string') {
177
+ console.info(`šŸ¤– Agent: ${lastMessage.content}\n`);
178
+ } else {
179
+ console.info(`šŸ¤– Agent:`, lastMessage.content, '\n');
180
+ }
181
+ }
182
+ } catch (error) {
183
+ const errorMsg = error instanceof Error ? error.message : String(error);
184
+ console.info(`āš ļø Agent error: ${errorMsg}\n`);
185
+ }
186
+ }
187
+
188
+ // Print summary
189
+ console.info('═'.repeat(60));
190
+ console.info('✨ GitHub AI Agent Tasks Complete!\n');
191
+ console.info('Key Features:');
192
+ console.info(' āœ… Real LLM (OpenAI) decides which GitHub tools to use');
193
+ console.info(' āœ… Natural language requests, not API calls');
194
+ console.info(' āœ… LLM generates tool parameters based on context');
195
+ console.info(' āœ… Agentic reasoning and decision-making\n');
196
+ } catch (error) {
197
+ console.error('āŒ Error:', error instanceof Error ? error.message : String(error));
198
+ if (error instanceof Error && error.stack) {
199
+ console.error('Stack:', error.stack);
200
+ }
201
+ process.exit(1);
202
+ }
203
+ }
204
+
205
+ // Run the AI agent
206
+ main().catch(console.error);
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env node
2
+
3
+ import 'dotenv/config';
4
+ import { MatimoInstance, getGlobalApprovalHandler, type ApprovalRequest } from '@matimo/core';
5
+ import * as readline from 'readline';
6
+
7
+ /**
8
+ * GitHub Tool Example with Destructive Operation Approval Flow
9
+ *
10
+ * This example demonstrates the NEW GENERIC approval system:
11
+ * 1. Loading GitHub tools via Matimo
12
+ * 2. Executing read-only operations (no approval needed)
13
+ * 3. Attempting destructive operations (requires approval)
14
+ * 4. Human-in-the-loop approval with interactive callback
15
+ *
16
+ * NEW Approval Flow (Generic for ALL tools):
17
+ * - Tool contains destructive keywords (CREATE, DELETE, DROP, UPDATE, MERGE, etc.)
18
+ * - Check MATIMO_AUTO_APPROVE=true (auto-approve all)
19
+ * - Check MATIMO_APPROVED_PATTERNS (pre-approved patterns)
20
+ * - Or call single generic approval callback for interactive approval
21
+ *
22
+ * Setup:
23
+ * ------
24
+ * 1. Create a GitHub Personal Access Token: https://github.com/settings/tokens
25
+ * export GITHUB_TOKEN=\"ghp_xxxx...\"
26
+ *
27
+ * 2. Run the example (interactive mode - you'll be prompted):
28
+ * pnpm github-with-approval
29
+ *
30
+ * 3. Or auto-approve in CI:
31
+ * export MATIMO_AUTO_APPROVE=true && pnpm github-with-approval
32
+ */
33
+
34
+ // Interactive approval callback for GitHub operations
35
+ function createApprovalCallback() {
36
+ return async (request: ApprovalRequest): Promise<boolean> => {
37
+ const isInteractive = process.stdin.isTTY;
38
+
39
+ console.info('\n' + '='.repeat(70));
40
+ console.info('šŸ”’ APPROVAL REQUIRED FOR DESTRUCTIVE GITHUB OPERATION');
41
+ console.info('='.repeat(70));
42
+ console.info(`\nšŸ“‹ Tool: ${request.toolName}`);
43
+ console.info(`šŸ“ Description: ${request.description || '(no description provided)'}`);
44
+
45
+ if (!isInteractive) {
46
+ console.info('\nāŒ REJECTED - Non-interactive environment (no terminal)');
47
+ console.info('\nšŸ’” To enable auto-approval in CI/scripts:');
48
+ console.info(' export MATIMO_AUTO_APPROVE=true');
49
+ console.info('\nšŸ’” Or approve specific patterns:');
50
+ console.info(' export MATIMO_APPROVED_PATTERNS="github-*"');
51
+ console.info('\n' + '='.repeat(70) + '\n');
52
+ return false;
53
+ }
54
+
55
+ // Interactive mode: prompt user
56
+ const rl = readline.createInterface({
57
+ input: process.stdin,
58
+ output: process.stdout,
59
+ });
60
+
61
+ return new Promise((resolve) => {
62
+ console.info('\nā“ User Action Required');
63
+ const question = ' Type "yes" to approve or "no" to reject: ';
64
+
65
+ rl.question(question, (answer) => {
66
+ const approved = answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y';
67
+
68
+ if (approved) {
69
+ console.info(' āœ… Operation APPROVED by user');
70
+ } else {
71
+ console.info(' āŒ Operation REJECTED by user');
72
+ }
73
+ console.info('='.repeat(70) + '\n');
74
+
75
+ rl.close();
76
+ resolve(approved);
77
+ });
78
+ });
79
+ };
80
+ }
81
+
82
+ async function main() {
83
+ console.info('\n' + '='.repeat(70));
84
+ console.info('šŸš€ GitHub Tools with Approval Flow');
85
+ console.info('='.repeat(70));
86
+
87
+ // Check for GitHub token
88
+ if (!process.env.GITHUB_TOKEN) {
89
+ console.error('\nāŒ Error: GITHUB_TOKEN environment variable not set');
90
+ console.info('\nšŸ“– Setup Instructions:');
91
+ console.info(' 1. Create a GitHub Personal Access Token:');
92
+ console.info(' https://github.com/settings/tokens');
93
+ console.info(' 2. Set the environment variable:');
94
+ console.info(' export GITHUB_TOKEN="ghp_xxxx..."');
95
+ console.info(' 3. Run this example again:');
96
+ console.info(' pnpm github-with-approval\n');
97
+ process.exit(1);
98
+ }
99
+
100
+ // Initialize Matimo with GitHub tools
101
+ const matimo = await MatimoInstance.init({
102
+ autoDiscover: true,
103
+ });
104
+
105
+ // Configure approval handler
106
+ const approvalHandler = getGlobalApprovalHandler();
107
+ approvalHandler.setApprovalCallback(createApprovalCallback());
108
+
109
+ // Show current approval mode
110
+ const autoApproveEnabled = process.env.MATIMO_AUTO_APPROVE === 'true';
111
+ const approvedPatterns = process.env.MATIMO_APPROVED_PATTERNS;
112
+
113
+ console.info('\nšŸ” APPROVAL CONFIGURATION:');
114
+ if (autoApproveEnabled) {
115
+ console.info(' āœ… MATIMO_AUTO_APPROVE=true');
116
+ console.info(' → All destructive operations will be AUTO-APPROVED');
117
+ } else if (approvedPatterns) {
118
+ console.info(` āœ… MATIMO_APPROVED_PATTERNS="${approvedPatterns}"`);
119
+ console.info(' → Matching operations will be auto-approved');
120
+ } else {
121
+ console.info(' āš ļø INTERACTIVE MODE ENABLED');
122
+ console.info(' → You will be prompted to approve destructive operations');
123
+ }
124
+
125
+ try {
126
+ // List available tools
127
+ const tools = matimo.listTools();
128
+ const githubTools = tools.filter((t) => t.name.startsWith('github-'));
129
+
130
+ // Destructive operations that require approval
131
+ const destructivePatterns = ['create-', 'delete-', 'merge-', 'update-', 'add-'];
132
+ const destructiveTools = githubTools.filter((t) =>
133
+ destructivePatterns.some((pattern) => t.name.includes(pattern))
134
+ );
135
+
136
+ console.info(`\nšŸ“‹ GitHub Tools Inventory:`);
137
+ console.info(` Total: ${githubTools.length}`);
138
+ console.info(` Destructive (require approval): ${destructiveTools.length}`);
139
+ console.info(
140
+ ` Read-only (no approval needed): ${githubTools.length - destructiveTools.length}\n`
141
+ );
142
+
143
+ console.info('šŸ“Š Sample Destructive Operations:');
144
+ destructiveTools.slice(0, 5).forEach((tool) => {
145
+ console.info(` - ${tool.name}`);
146
+ });
147
+ if (destructiveTools.length > 5) {
148
+ console.info(` ... and ${destructiveTools.length - 5} more\n`);
149
+ }
150
+
151
+ // Example 1: Read-only operation (no approval needed)
152
+ console.info('═'.repeat(70));
153
+ console.info('Example 1: Read-Only Operation');
154
+ console.info('═'.repeat(70));
155
+ console.info('\nšŸ“– Operation: Search repositories (no approval needed)');
156
+ console.info(' Tool: github-search-repositories');
157
+ console.info(' Type: Read-only\n');
158
+ try {
159
+ const searchResults = await matimo.execute('github-search-repositories', {
160
+ query: 'language:typescript fork:false stars:>100',
161
+ });
162
+ const data = (searchResults as any).data || searchResults;
163
+ console.info(`āœ… Success: Found ${data?.total_count} repositories\n`);
164
+ } catch (error: any) {
165
+ console.error(`āŒ Error: ${error.message}\n`);
166
+ }
167
+
168
+ // Example 2: Read-only operation (no approval needed)
169
+ console.info('═'.repeat(60));
170
+ console.info('Example 2: Get Repository Details');
171
+ console.info('═'.repeat(60));
172
+ console.info('\nšŸ“– Operation: Get repository details (no approval needed)');
173
+ console.info(' Tool: github-get-repository\n');
174
+ try {
175
+ const repo = await matimo.execute('github-get-repository', {
176
+ owner: 'kubernetes',
177
+ repo: 'kubernetes',
178
+ });
179
+ const data = (repo as any).data || repo;
180
+ console.info(`āœ… Success: Retrieved repo details for ${data?.full_name}\n`);
181
+ } catch (error: any) {
182
+ console.error(`āŒ Error: ${error.message}\n`);
183
+ }
184
+ // Add more examples for destructive operations here (they will require approval).
185
+ console.info('═'.repeat(70));
186
+ console.info('šŸ“Š Approval System Summary');
187
+ console.info('═'.repeat(70));
188
+ console.info('\nšŸ’” How Approval Works:');
189
+ console.info(' 1. Read-only operations (list, get, search) execute immediately');
190
+ console.info(' 2. Destructive operations (create, delete, merge, update, add)');
191
+ console.info(' are detected and require approval before execution');
192
+ console.info(' 3. Approval is controlled by environment or interactive callback:');
193
+
194
+ console.info('\nšŸ” Supported Approval Modes:');
195
+ console.info(' • MATIMO_AUTO_APPROVE=true → Approve all destructive operations');
196
+ console.info(
197
+ ' • MATIMO_APPROVED_PATTERNS → Approve only matching tool names (glob pattern)'
198
+ );
199
+ console.info(' • Interactive (no env vars) → Prompt user for each operation');
200
+
201
+ console.info('\nšŸ’” How to Use:');
202
+ console.info(' 1. Interactive (default): pnpm github-with-approval');
203
+ console.info(
204
+ ' 2. Auto-approve in CI: MATIMO_AUTO_APPROVE=true pnpm github-with-approval'
205
+ );
206
+ console.info(
207
+ ' 3. Pre-approved patterns: MATIMO_APPROVED_PATTERNS="github-*" pnpm github-with-approval'
208
+ );
209
+
210
+ console.info('\nāœ… Read-Only Examples Completed Successfully!');
211
+ console.info('\nNote: Destructive operations in tests are only read-only GitHub operations.');
212
+ console.info(
213
+ ' To test destructive approvals, you would need creation/deletion permissions.\n'
214
+ );
215
+ console.info('='.repeat(70) + '\n');
216
+ } catch (error: any) {
217
+ console.error('\nāŒ Fatal Error:', error.message);
218
+ if (error.details) {
219
+ console.error('Details:', JSON.stringify(error.details, null, 2));
220
+ }
221
+ process.exit(1);
222
+ }
223
+ }
224
+
225
+ main().catch((err) => {
226
+ console.error('Fatal error:', err);
227
+ process.exit(1);
228
+ });