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,292 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ============================================================================
4
+ * EDIT TOOL - LANGCHAIN AI AGENT EXAMPLE
5
+ * ============================================================================
6
+ *
7
+ * PATTERN: True AI Agent with OpenAI + LangChain
8
+ * ─────────────────────────────────────────────────────────────────────────
9
+ * This is a REAL AI agent that:
10
+ * 1. Takes natural language user requests
11
+ * 2. Uses OpenAI LLM (GPT-4o-mini) to decide which edit operations to use
12
+ * 3. Generates appropriate parameters based on context
13
+ * 4. Executes tools autonomously
14
+ * 5. Processes results and responds naturally
15
+ *
16
+ * Use this pattern when:
17
+ * ✅ Building true autonomous AI agents
18
+ * ✅ LLM should decide which tools to use
19
+ * ✅ Complex workflows with LLM reasoning
20
+ * ✅ Multi-step agentic processes
21
+ * ✅ User gives high-level instructions (not low-level API calls)
22
+ *
23
+ * SETUP:
24
+ * ─────────────────────────────────────────────────────────────────────────
25
+ * 1. Create .env file in examples/tools/:
26
+ * OPENAI_API_KEY=sk-xxxxxxxxxxxxx
27
+ *
28
+ * 2. Install dependencies:
29
+ * cd examples/tools && npm install
30
+ *
31
+ * USAGE:
32
+ * ─────────────────────────────────────────────────────────────────────────
33
+ * # From root directory:
34
+ * pnpm edit:langchain
35
+ *
36
+ * # Or from examples/tools directory:
37
+ * npm run edit:langchain
38
+ *
39
+ * WHAT IT DOES:
40
+ * ─────────────────────────────────────────────────────────────────────────
41
+ * This example shows an AI agent that can:
42
+ * 1. Replace text in files
43
+ * 2. Insert new content
44
+ * 3. Delete lines
45
+ * 4. Append to files
46
+ * 5. Respond naturally in conversation style
47
+ *
48
+ * Example conversation:
49
+ * User: "Update the TODO list - mark first item as DONE and add error handling"
50
+ * AI Agent: "I'll help you update the TODO list..."
51
+ * [AI Agent calls edit tool multiple times]
52
+ * AI Agent: "Done! I've updated the file with your changes."
53
+ *
54
+ * ============================================================================
55
+ */
56
+
57
+ import 'dotenv/config';
58
+ import fs from 'fs';
59
+ import path from 'path';
60
+ import { fileURLToPath } from 'url';
61
+ import * as readline from 'readline';
62
+ import { createAgent } from 'langchain';
63
+ import { ChatOpenAI } from '@langchain/openai';
64
+ import {
65
+ MatimoInstance,
66
+ convertToolsToLangChain,
67
+ type ToolDefinition,
68
+ getGlobalApprovalHandler,
69
+ type ApprovalRequest,
70
+ } from '@matimo/core';
71
+
72
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
73
+
74
+ /**
75
+ * Create an interactive approval callback for file operations
76
+ */
77
+ function createApprovalCallback() {
78
+ return async (request: ApprovalRequest): Promise<boolean> => {
79
+ const isInteractive = process.stdin.isTTY;
80
+
81
+ console.info('\n' + '='.repeat(70));
82
+ console.info('🔒 APPROVAL REQUIRED FOR FILE OPERATION');
83
+ console.info('='.repeat(70));
84
+ console.info(`\n📋 Tool: ${request.toolName}`);
85
+ console.info(`📝 Description: ${request.description || '(no description provided)'}`);
86
+ console.info(`\n📄 File Operation:`);
87
+ console.info(` Path: ${request.params.filePath}`);
88
+ if (request.params.startLine) {
89
+ console.info(` Start Line: ${request.params.startLine}`);
90
+ }
91
+ if (request.params.endLine) {
92
+ console.info(` End Line: ${request.params.endLine}`);
93
+ }
94
+
95
+ if (!isInteractive) {
96
+ console.info('\n❌ REJECTED - Non-interactive environment (no terminal)');
97
+ console.info('\n💡 To enable auto-approval in CI/scripts:');
98
+ console.info(' export MATIMO_AUTO_APPROVE=true');
99
+ console.info('\n💡 Or approve specific patterns:');
100
+ console.info(' export MATIMO_APPROVED_PATTERNS="edit"');
101
+ console.info('\n' + '='.repeat(70) + '\n');
102
+ return false;
103
+ }
104
+
105
+ // Interactive mode: prompt user
106
+ const rl = readline.createInterface({
107
+ input: process.stdin,
108
+ output: process.stdout,
109
+ });
110
+
111
+ return new Promise((resolve) => {
112
+ console.info('\n❓ User Action Required');
113
+ const question = ' Type "yes" to approve or "no" to reject: ';
114
+
115
+ rl.question(question, (answer) => {
116
+ const approved = answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y';
117
+
118
+ if (approved) {
119
+ console.info(' ✅ Operation APPROVED by user');
120
+ } else {
121
+ console.info(' ❌ Operation REJECTED by user');
122
+ }
123
+ console.info('='.repeat(70) + '\n');
124
+
125
+ rl.close();
126
+ resolve(approved);
127
+ });
128
+ });
129
+ };
130
+ }
131
+
132
+ /**
133
+ * Run AI Agent with Edit tools
134
+ * The agent receives natural language requests and decides which edit operations to use
135
+ */
136
+ async function runEditAIAgent() {
137
+ console.info('\n╔════════════════════════════════════════════════════════╗');
138
+ console.info('║ Edit Tool AI Agent - LangChain + OpenAI ║');
139
+ console.info('║ True autonomous agent with LLM reasoning ║');
140
+ console.info('╚════════════════════════════════════════════════════════╝\n');
141
+
142
+ // Check required environment variables
143
+ const openaiKey = process.env.OPENAI_API_KEY;
144
+ if (!openaiKey) {
145
+ console.error('❌ Error: OPENAI_API_KEY not set in .env');
146
+ console.info(' Set it: export OPENAI_API_KEY="sk-..."');
147
+ console.info(' Get one from: https://platform.openai.com/api-keys');
148
+ process.exit(1);
149
+ }
150
+
151
+ console.info('🤖 Using OpenAI (GPT-4o-mini) as the AI agent\n');
152
+
153
+ // Create a temp file for the agent to work with
154
+ const tempFile = path.join(__dirname, 'temp-agent-edit-demo.txt');
155
+ fs.writeFileSync(
156
+ tempFile,
157
+ `Project TODO List
158
+ ================
159
+ - TODO: Implement authentication module
160
+ - TODO: Add database migrations
161
+ - TODO: Write API documentation
162
+ - TODO: Set up CI/CD pipeline
163
+ `
164
+ );
165
+
166
+ try {
167
+ // Initialize Matimo with auto-discovery
168
+ console.info('🚀 Initializing Matimo...');
169
+ const matimo = await MatimoInstance.init({ autoDiscover: true });
170
+
171
+ // Configure centralized approval handler
172
+ const approvalHandler = getGlobalApprovalHandler();
173
+ approvalHandler.setApprovalCallback(createApprovalCallback());
174
+
175
+ // Get edit tool
176
+ console.info('💬 Loading edit tool...');
177
+ const matimoTools = matimo.listTools();
178
+ const editTools = matimoTools.filter((t) => t.name === 'edit') as ToolDefinition[];
179
+ console.info(`✅ Loaded ${editTools.length} edit tool(s)\n`);
180
+
181
+ if (editTools.length === 0) {
182
+ console.error('❌ Edit tool not found');
183
+ process.exit(1);
184
+ }
185
+
186
+ // Convert to LangChain tools using the built-in converter
187
+ const langchainTools = await convertToolsToLangChain(editTools, matimo);
188
+
189
+ // Initialize OpenAI LLM
190
+ console.info('🤖 Initializing OpenAI (GPT-4o-mini) LLM...');
191
+ const model = new ChatOpenAI({
192
+ modelName: 'gpt-4o-mini',
193
+ temperature: 0.7,
194
+ });
195
+
196
+ // Create agent
197
+ console.info('🔧 Creating agent...\n');
198
+ const agent = await createAgent({
199
+ model,
200
+ tools: langchainTools as any,
201
+ });
202
+
203
+ // Define agent tasks (natural language requests)
204
+ const userRequests = [
205
+ {
206
+ title: 'Example 1: Replace TODO with DONE',
207
+ request: `Mark the first authentication TODO as DONE in file ${tempFile}. Then describe what you did.`,
208
+ },
209
+ {
210
+ title: 'Example 2: Insert new item',
211
+ request: `Add a new TODO "Set up error logging" after line 5 in file ${tempFile}. Confirm the action and tell me how many lines were affected.`,
212
+ },
213
+ {
214
+ title: 'Example 3: List file content',
215
+ request: `Show me the current content of file ${tempFile} (use read tool if available, or describe the final state after your edits)`,
216
+ },
217
+ ];
218
+
219
+ console.info('🧪 Running AI Agent Tasks');
220
+ console.info('═'.repeat(60));
221
+ console.info(`📁 Working with: ${tempFile}\n`);
222
+
223
+ // Show initial file content
224
+ console.info('📄 Initial file content:');
225
+ console.info('─'.repeat(60));
226
+ console.info(fs.readFileSync(tempFile, 'utf-8'));
227
+ console.info('─'.repeat(60) + '\n');
228
+
229
+ // Run each task through the agent
230
+ for (const task of userRequests) {
231
+ console.info(`${task.title}`);
232
+ console.info('─'.repeat(60));
233
+ console.info(`👤 User: "${task.request}"\n`);
234
+
235
+ try {
236
+ const response = await agent.invoke({
237
+ messages: [
238
+ {
239
+ role: 'user',
240
+ content: task.request,
241
+ },
242
+ ],
243
+ });
244
+
245
+ // Get the last message from the agent
246
+ const lastMessage = response.messages[response.messages.length - 1];
247
+ if (lastMessage) {
248
+ const content =
249
+ typeof lastMessage.content === 'string'
250
+ ? lastMessage.content
251
+ : String(lastMessage.content);
252
+
253
+ console.info(`🤖 Agent: ${content || '(Tool executed successfully)'}\n`);
254
+ }
255
+ } catch (error) {
256
+ const errorMsg = error instanceof Error ? error.message : String(error);
257
+ console.info(`⚠️ Agent error: ${errorMsg}\n`);
258
+ }
259
+ }
260
+
261
+ console.info('═'.repeat(60));
262
+ console.info('\n📄 Final file content:');
263
+ console.info('─'.repeat(60));
264
+ console.info(fs.readFileSync(tempFile, 'utf-8'));
265
+ console.info('─'.repeat(60));
266
+
267
+ console.info('\n✨ AI Agent Examples Complete!\n');
268
+ console.info('Key Features:');
269
+ console.info(' ✅ Real LLM (OpenAI) decides which tools to use');
270
+ console.info(' ✅ Natural language requests, not API calls');
271
+ console.info(' ✅ LLM generates tool parameters based on context');
272
+ console.info(' ✅ Agentic reasoning and decision-making\n');
273
+ console.info('⚠️ Note on agent responses:');
274
+ console.info(' The agent DOES call the real LLM to decide which tool to use.');
275
+ console.info(' However, LangChain agents generate minimal responses when tools succeed.');
276
+ console.info(' The agent autonomously executes tools without verbose narration.\n');
277
+ } catch (error) {
278
+ console.error('❌ Error:', error instanceof Error ? error.message : String(error));
279
+ if (error instanceof Error && error.stack) {
280
+ console.error('Stack:', error.stack);
281
+ }
282
+ process.exit(1);
283
+ } finally {
284
+ // Clean up
285
+ if (fs.existsSync(tempFile)) {
286
+ fs.unlinkSync(tempFile);
287
+ }
288
+ }
289
+ }
290
+
291
+ // Run the AI agent
292
+ runEditAIAgent().catch(console.error);
@@ -0,0 +1,49 @@
1
+ import { MatimoInstance, setGlobalMatimoInstance, tool } from '@matimo/core';
2
+
3
+ /**
4
+ * Example: Execute tool using @tool decorator pattern
5
+ * Demonstrates class-based tool execution with automatic decoration
6
+ */
7
+ class CommandExecutor {
8
+ @tool('execute')
9
+ async runCommand(command: string, timeout?: number): Promise<unknown> {
10
+ // Decorator automatically intercepts and executes via Matimo
11
+ return undefined;
12
+ }
13
+
14
+ @tool('execute')
15
+ async listDirectory(): Promise<unknown> {
16
+ // Decorator automatically intercepts and executes via Matimo
17
+ return undefined;
18
+ }
19
+ }
20
+
21
+ async function decoratorExample() {
22
+ // Set up decorator support with autoDiscover
23
+ const matimo = await MatimoInstance.init({ autoDiscover: true });
24
+ setGlobalMatimoInstance(matimo);
25
+
26
+ console.info('=== Execute Tool - Decorator Pattern ===\n');
27
+
28
+ const executor = new CommandExecutor();
29
+
30
+ try {
31
+ // Example 1: Run command through decorated method
32
+ console.info('1. Running command: echo "Hello from decorator"\n');
33
+ const result1 = await executor.runCommand('echo "Hello from decorator"');
34
+ console.info('Success:', (result1 as any).success);
35
+ console.info('Output:', (result1 as any).stdout);
36
+ console.info('---\n');
37
+
38
+ // Example 2: List directory
39
+ console.info('2. Running command: pwd\n');
40
+ const result2 = await executor.listDirectory();
41
+ console.info('Success:', (result2 as any).success);
42
+ console.info('Output:', (result2 as any).stdout);
43
+ console.info('---\n');
44
+ } catch (error: any) {
45
+ console.error('Error:', error.message);
46
+ }
47
+ }
48
+
49
+ decoratorExample();
@@ -0,0 +1,46 @@
1
+ import { MatimoInstance } from '@matimo/core';
2
+
3
+ /**
4
+ * Example: Execute tool using factory pattern
5
+ * Demonstrates running shell commands and capturing output
6
+ */
7
+ async function executeExample() {
8
+ // Initialize Matimo with autoDiscover to find all tools (core + providers)
9
+ const matimo = await MatimoInstance.init({ autoDiscover: true });
10
+
11
+ console.info('=== Execute Tool - Factory Pattern ===\n');
12
+
13
+ try {
14
+ // Example 1: List files in current directory
15
+ console.info('1. Running: ls\n');
16
+ const lsResult = await matimo.execute('execute', {
17
+ command: 'ls',
18
+ timeout: 10000,
19
+ });
20
+ console.info('Success:', (lsResult as any).success);
21
+ console.info('Output:', (lsResult as any).stdout?.substring(0, 200));
22
+ console.info('---\n');
23
+
24
+ // Example 2: Get current working directory
25
+ console.info('2. Running: pwd\n');
26
+ const pwdResult = await matimo.execute('execute', {
27
+ command: 'pwd',
28
+ });
29
+ console.info('Success:', (pwdResult as any).success);
30
+ console.info('Output:', (pwdResult as any).stdout);
31
+ console.info('---\n');
32
+
33
+ // Example 3: Echo command
34
+ console.info('3. Running: echo "Hello from Matimo"\n');
35
+ const echoResult = await matimo.execute('execute', {
36
+ command: 'echo "Hello from Matimo"',
37
+ });
38
+ console.info('Success:', (echoResult as any).success);
39
+ console.info('Output:', (echoResult as any).stdout);
40
+ console.info('---\n');
41
+ } catch (error: any) {
42
+ console.error('Error executing command:', error.message);
43
+ }
44
+ }
45
+
46
+ executeExample();
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ============================================================================
4
+ * EXECUTE TOOL - LANGCHAIN AI AGENT EXAMPLE
5
+ * ============================================================================
6
+ *
7
+ * PATTERN: True AI Agent with OpenAI + LangChain
8
+ * ─────────────────────────────────────────────────────────────────────────
9
+ * This is a REAL AI agent that:
10
+ * 1. Takes natural language user requests
11
+ * 2. Uses OpenAI LLM (GPT-4o-mini) to decide when to execute commands
12
+ * 3. Generates appropriate command parameters based on context
13
+ * 4. Executes tools autonomously
14
+ * 5. Processes results and responds naturally
15
+ *
16
+ * SETUP:
17
+ * ─────────────────────────────────────────────────────────────────────────
18
+ * 1. Create .env file:
19
+ * OPENAI_API_KEY=sk-xxxxxxxxxxxxx
20
+ *
21
+ * 2. Install dependencies:
22
+ * npm install
23
+ *
24
+ * USAGE:
25
+ * ─────────────────────────────────────────────────────────────────────────
26
+ * export OPENAI_API_KEY=sk-xxxx
27
+ * npm run execute:langchain
28
+ *
29
+ * ============================================================================
30
+ */
31
+
32
+ import 'dotenv/config';
33
+ import * as readline from 'readline';
34
+ import { createAgent } from 'langchain';
35
+ import { ChatOpenAI } from '@langchain/openai';
36
+ import {
37
+ MatimoInstance,
38
+ convertToolsToLangChain,
39
+ ToolDefinition,
40
+ getGlobalApprovalHandler,
41
+ type ApprovalRequest,
42
+ } from '@matimo/core';
43
+
44
+ /**
45
+ * Create an interactive approval callback for command execution
46
+ */
47
+ function createApprovalCallback() {
48
+ return async (request: ApprovalRequest): Promise<boolean> => {
49
+ // Check both process.stdin.isTTY and if stdin is readable
50
+ const isInteractive = process.stdin.isTTY && process.stdin.readable;
51
+
52
+ console.info('\n' + '='.repeat(70));
53
+ console.info('🔒 APPROVAL REQUIRED FOR COMMAND EXECUTION');
54
+ console.info('='.repeat(70));
55
+ console.info(`\n📋 Tool: ${request.toolName}`);
56
+ console.info(`📝 Description: ${request.description || '(no description provided)'}`);
57
+ console.info(`\n💻 Command Operation:`);
58
+ console.info(` Command: ${request.params.command}`);
59
+ if (request.params.cwd) {
60
+ console.info(` Working Dir: ${request.params.cwd}`);
61
+ }
62
+
63
+ if (!isInteractive) {
64
+ console.info('\n❌ REJECTED - Non-interactive environment (stdin not available)');
65
+ console.info('\n💡 To auto-approve in non-interactive environments:');
66
+ console.info(' export MATIMO_AUTO_APPROVE=true');
67
+ console.info('\n💡 Or pre-approve specific patterns:');
68
+ console.info(' export MATIMO_APPROVED_PATTERNS="execute"');
69
+ console.info('\n💡 To test interactively, run from command line:');
70
+ console.info(' npm run execute:langchain');
71
+ console.info('\n' + '='.repeat(70) + '\n');
72
+ return false;
73
+ }
74
+
75
+ // Interactive mode: prompt user
76
+ const rl = readline.createInterface({
77
+ input: process.stdin,
78
+ output: process.stdout,
79
+ terminal: true,
80
+ });
81
+
82
+ return new Promise((resolve) => {
83
+ console.info('\n❓ User Action Required');
84
+ const question = ' Type "yes" to approve or "no" to reject: ';
85
+
86
+ rl.question(question, (answer) => {
87
+ const approved = answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y';
88
+
89
+ if (approved) {
90
+ console.info(' ✅ Operation APPROVED by user');
91
+ } else {
92
+ console.info(' ❌ Operation REJECTED by user');
93
+ }
94
+ console.info('='.repeat(70) + '\n');
95
+
96
+ rl.close();
97
+ resolve(approved);
98
+ });
99
+ });
100
+ };
101
+ }
102
+
103
+ /**
104
+ * The agent receives natural language requests and decides which commands to execute
105
+ */
106
+ async function runExecuteAIAgent() {
107
+ console.info('\n╔════════════════════════════════════════════════════════╗');
108
+ console.info('║ Execute Tool AI Agent - LangChain + OpenAI ║');
109
+ console.info('║ True autonomous agent with LLM reasoning ║');
110
+ console.info('╚════════════════════════════════════════════════════════╝\n');
111
+
112
+ // Check required environment variables
113
+ const openaiKey = process.env.OPENAI_API_KEY;
114
+ if (!openaiKey) {
115
+ console.error('❌ Error: OPENAI_API_KEY not set in .env');
116
+ console.info(' Set it: export OPENAI_API_KEY="sk-..."');
117
+ console.info(' Get one from: https://platform.openai.com/api-keys');
118
+ process.exit(1);
119
+ }
120
+
121
+ console.info('🤖 Using OpenAI (GPT-4o-mini) as the AI agent\n');
122
+
123
+ try {
124
+ // Initialize Matimo with auto-discovery
125
+ console.info('🚀 Initializing Matimo...');
126
+ const matimo = await MatimoInstance.init({ autoDiscover: true });
127
+
128
+ // Get execute tool
129
+ console.info('💬 Loading execute tool...');
130
+ const matimoTools = matimo.listTools();
131
+ const executeTools = matimoTools.filter((t) => t.name === 'execute');
132
+ console.info(`✅ Loaded ${executeTools.length} execute tool(s)\n`);
133
+
134
+ if (executeTools.length === 0) {
135
+ console.error('❌ Execute tool not found');
136
+ process.exit(1);
137
+ }
138
+
139
+ // Convert to LangChain tools using the built-in converter
140
+ const langchainTools = await convertToolsToLangChain(executeTools as ToolDefinition[], matimo);
141
+
142
+ // Set up approval callback for destructive commands
143
+ const approvalHandler = getGlobalApprovalHandler();
144
+ approvalHandler.setApprovalCallback(createApprovalCallback());
145
+
146
+ // Initialize OpenAI LLM
147
+ console.info('🤖 Initializing OpenAI (GPT-4o-mini) LLM...');
148
+ const model = new ChatOpenAI({
149
+ modelName: 'gpt-4o-mini',
150
+ temperature: 0.7,
151
+ });
152
+
153
+ // Create agent
154
+ console.info('🔧 Creating agent...\n');
155
+ const agent = await createAgent({
156
+ model,
157
+ tools: langchainTools as any,
158
+ });
159
+
160
+ // Define agent tasks (natural language requests)
161
+ const userRequests = [
162
+ {
163
+ title: 'Example 1: Get system information',
164
+ request: 'Show me the current working directory using pwd command',
165
+ },
166
+ {
167
+ title: 'Example 2: List files',
168
+ request: 'List files and directories in the current folder (use ls -la)',
169
+ },
170
+ {
171
+ title: 'Example 3: Create a test file',
172
+ request: 'Create a simple test file named test.txt in /tmp with content "Hello from Agent"',
173
+ },
174
+ ];
175
+
176
+ console.info('🧪 Running AI Agent Tasks');
177
+ console.info('═'.repeat(60) + '\n');
178
+
179
+ // Run each task through the agent
180
+ for (const task of userRequests) {
181
+ console.info(`${task.title}`);
182
+ console.info('─'.repeat(60));
183
+ console.info(`👤 User: "${task.request}"\n`);
184
+
185
+ try {
186
+ const response = await agent.invoke({
187
+ messages: [
188
+ {
189
+ role: 'user',
190
+ content: task.request,
191
+ },
192
+ ],
193
+ });
194
+
195
+ // Get the last message from the agent
196
+ const lastMessage = response.messages[response.messages.length - 1];
197
+ if (lastMessage) {
198
+ const content =
199
+ typeof lastMessage.content === 'string'
200
+ ? lastMessage.content
201
+ : String(lastMessage.content);
202
+
203
+ if (content && content.trim()) {
204
+ console.info(`🤖 Agent: ${content}\n`);
205
+ } else {
206
+ console.info('🤖 Agent: (Command executed successfully)\n');
207
+ }
208
+ }
209
+ } catch (error) {
210
+ const errorMsg = error instanceof Error ? error.message : String(error);
211
+ console.info(`⚠️ Agent error: ${errorMsg}\n`);
212
+ }
213
+ }
214
+
215
+ console.info('═'.repeat(60));
216
+ console.info('\n✨ AI Agent Examples Complete!\n');
217
+ console.info('Key Features:');
218
+ console.info(' ✅ Real LLM (OpenAI) decides which tools to use');
219
+ console.info(' ✅ Natural language requests, not API calls');
220
+ console.info(' ✅ LLM generates command parameters based on context');
221
+ console.info(' ✅ Agentic reasoning and decision-making\n');
222
+ } catch (error) {
223
+ console.error('❌ Error:', error instanceof Error ? error.message : String(error));
224
+ if (error instanceof Error && error.stack) {
225
+ console.error('Stack:', error.stack);
226
+ }
227
+ process.exit(1);
228
+ }
229
+ }
230
+
231
+ // Run the AI agent
232
+ runExecuteAIAgent().catch(console.error);