modular-agent-examples 0.0.1

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 (44) hide show
  1. package/chunking-demo.ts +339 -0
  2. package/cleanup-duplicates.ts +142 -0
  3. package/data/flower.jpg +0 -0
  4. package/generative.ts +128 -0
  5. package/graph/context-example.ts +209 -0
  6. package/graph/data-pipeline/agents.ts +60 -0
  7. package/graph/data-pipeline/fetchers.ts +166 -0
  8. package/graph/data-pipeline/index.ts +282 -0
  9. package/graph/index.ts +154 -0
  10. package/graph/map-example.ts +227 -0
  11. package/graph/metrics-example.ts +238 -0
  12. package/graph/parallel-example.ts +167 -0
  13. package/graph/pipeline-example.ts +225 -0
  14. package/graph/planning-example.ts +406 -0
  15. package/graph/router-example.ts +226 -0
  16. package/graph/sequential-example.ts +141 -0
  17. package/graph/voting-example.ts +159 -0
  18. package/graph-rag/docker-compose.yaml +14 -0
  19. package/graph-rag/index.js +99 -0
  20. package/graph-rag/init-db.sh +7 -0
  21. package/graph-rag/package.json +15 -0
  22. package/history-compression-example.ts +163 -0
  23. package/history-persistence.ts +347 -0
  24. package/index.ts +175 -0
  25. package/ingestion-pipeline.ts +353 -0
  26. package/mcp-airbnb-example.ts +69 -0
  27. package/mcp-http-example.ts +70 -0
  28. package/mcp-stdio-example.ts +63 -0
  29. package/multimodal.ts +144 -0
  30. package/ollama.ts +148 -0
  31. package/openai-compatible.ts +141 -0
  32. package/opensearch-vector-store.ts +342 -0
  33. package/package.json +24 -0
  34. package/pubmed.ts +289 -0
  35. package/reasoning-with-sub-agent.ts +311 -0
  36. package/synchronous/index.ts +48 -0
  37. package/tsconfig.json +8 -0
  38. package/vector-store-filtering.ts +303 -0
  39. package/vector-store.ts +210 -0
  40. package/vectorstore/index.ts +0 -0
  41. package/vectorstore/store/dbService.ts +80 -0
  42. package/voyage-embeddings.ts +99 -0
  43. package/weather-with-sub-agent.ts +276 -0
  44. package/weather.ts +389 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Shared Context Example
3
+ *
4
+ * This example demonstrates how multiple agents can share data
5
+ * through a common context store using tools.
6
+ *
7
+ * Run with: npx ts-node examples/graph/context-example.ts
8
+ */
9
+
10
+ import { AgentGraph } from "../../lib/graph/AgentGraph";
11
+ import { ClaudeAgent } from "../../lib/agents/anthropic/ClaudeAgent";
12
+
13
+ async function main() {
14
+ // Create a shared context store with initial values
15
+ const contextStore = AgentGraph.createContextStore({
16
+ user_preferences: {
17
+ language: "English",
18
+ detail_level: "comprehensive",
19
+ },
20
+ });
21
+
22
+ // Create context tools that all agents will share
23
+ const contextTools = AgentGraph.createContextTools(contextStore);
24
+
25
+ // Agent 1: Researcher - gathers information and stores in context
26
+ const researcher = new ClaudeAgent({
27
+ id: "researcher",
28
+ name: "Research Agent",
29
+ description: `You are a research agent. Your job is to:
30
+ 1. Research the given topic
31
+ 2. Store your findings in context using context_set with key "research_findings"
32
+ 3. Store a list of key points using context_set with key "key_points"
33
+
34
+ Use clear, descriptive keys for all context values.`,
35
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
36
+ model: "claude-sonnet-4-20250514",
37
+ maxTokens: 2048,
38
+ tools: contextTools,
39
+ });
40
+
41
+ // Agent 2: Analyst - reads research and adds analysis
42
+ const analyst = new ClaudeAgent({
43
+ id: "analyst",
44
+ name: "Analysis Agent",
45
+ description: `You are an analysis agent. Your job is to:
46
+ 1. First, use list_context_keys to see what data is available
47
+ 2. Use context_get to retrieve "research_findings" and "key_points"
48
+ 3. Analyze the research and identify patterns, insights, and implications
49
+ 4. Store your analysis using context_set with key "analysis_results"
50
+
51
+ Build upon the research already in context.`,
52
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
53
+ model: "claude-sonnet-4-20250514",
54
+ maxTokens: 2048,
55
+ tools: contextTools,
56
+ });
57
+
58
+ // Agent 3: Writer - reads everything and creates final output
59
+ const writer = new ClaudeAgent({
60
+ id: "writer",
61
+ name: "Writer Agent",
62
+ description: `You are a writing agent. Your job is to:
63
+ 1. Use list_context_keys to see all available data
64
+ 2. Use context_get to retrieve research findings, key points, and analysis results
65
+ 3. Also check user_preferences for language and detail level preferences
66
+ 4. Write a well-structured report combining all the information
67
+ 5. Store the final report using context_set with key "final_report"
68
+
69
+ Create a cohesive narrative from all the gathered information.`,
70
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
71
+ model: "claude-sonnet-4-20250514",
72
+ maxTokens: 2048,
73
+ tools: contextTools,
74
+ });
75
+
76
+ const topic = "The impact of artificial intelligence on software development workflows";
77
+
78
+ console.log(`\n=== Shared Context Pipeline ===\n`);
79
+ console.log(`Topic: ${topic}\n`);
80
+ console.log("Initial context:", contextStore.toObject());
81
+
82
+ try {
83
+ // Step 1: Research
84
+ console.log("\n--- Step 1: Research ---");
85
+ await researcher.execute(
86
+ `Research the following topic and store your findings in context: "${topic}"`
87
+ );
88
+ console.log("Context keys after research:", contextStore.keys());
89
+
90
+ // Step 2: Analysis
91
+ console.log("\n--- Step 2: Analysis ---");
92
+ await analyst.execute(
93
+ "Retrieve the research from context, analyze it, and store your analysis."
94
+ );
95
+ console.log("Context keys after analysis:", contextStore.keys());
96
+
97
+ // Step 3: Writing
98
+ console.log("\n--- Step 3: Writing ---");
99
+ await writer.execute(
100
+ "Retrieve all information from context and write a comprehensive report."
101
+ );
102
+ console.log("Context keys after writing:", contextStore.keys());
103
+
104
+ // Display final results
105
+ console.log("\n=== Final Context Contents ===\n");
106
+
107
+ const allKeys = contextStore.keys();
108
+ for (const key of allKeys) {
109
+ const value = contextStore.get(key);
110
+ console.log(`\n[${key}]:`);
111
+ if (typeof value === "string") {
112
+ // Truncate long strings for display
113
+ console.log(value.length > 500 ? value.substring(0, 500) + "..." : value);
114
+ } else {
115
+ console.log(JSON.stringify(value, null, 2));
116
+ }
117
+ }
118
+ } catch (error) {
119
+ console.error("Error:", error);
120
+ }
121
+ }
122
+
123
+ // Alternative: Using context in a pipeline
124
+ async function pipelineExample() {
125
+ console.log("\n\n=== Context in Pipeline Example ===\n");
126
+
127
+ const contextStore = AgentGraph.createContextStore();
128
+ const contextTools = AgentGraph.createContextTools(contextStore);
129
+
130
+ // Simple agents that use context
131
+ const agent1 = new ClaudeAgent({
132
+ id: "agent1",
133
+ name: "Agent 1",
134
+ description:
135
+ "You receive input and store it in context with key 'stage1_output'. " +
136
+ "Also add your own observations with key 'stage1_observations'.",
137
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
138
+ model: "claude-sonnet-4-20250514",
139
+ maxTokens: 1024,
140
+ tools: contextTools,
141
+ });
142
+
143
+ const agent2 = new ClaudeAgent({
144
+ id: "agent2",
145
+ name: "Agent 2",
146
+ description:
147
+ "First retrieve 'stage1_output' and 'stage1_observations' from context. " +
148
+ "Then process them and store result with key 'stage2_output'.",
149
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
150
+ model: "claude-sonnet-4-20250514",
151
+ maxTokens: 1024,
152
+ tools: contextTools,
153
+ });
154
+
155
+ // Create a sequential pipeline
156
+ const pipeline = AgentGraph.sequential({ wrapInput: false }, agent1, agent2);
157
+
158
+ try {
159
+ const result = await pipeline.execute("Process this: Hello, World!");
160
+
161
+ console.log("Pipeline result:", result.substring(0, 200));
162
+ console.log("\nContext after pipeline:");
163
+ console.log(contextStore.toObject());
164
+ } catch (error) {
165
+ console.error("Error:", error);
166
+ }
167
+ }
168
+
169
+ // Demonstration without API calls (using the store directly)
170
+ function storeDemo() {
171
+ console.log("\n\n=== Context Store Demo (No API) ===\n");
172
+
173
+ const store = AgentGraph.createContextStore({
174
+ initial_value: "hello",
175
+ });
176
+
177
+ // Set various types of values
178
+ store.set("string_value", "This is a string");
179
+ store.set("number_value", 42);
180
+ store.set("object_value", { nested: { data: [1, 2, 3] } });
181
+ store.set("array_value", ["a", "b", "c"]);
182
+
183
+ console.log("All keys:", store.keys());
184
+ console.log("Has 'string_value':", store.has("string_value"));
185
+ console.log("Get 'object_value':", store.get("object_value"));
186
+ console.log("Size:", store.size);
187
+
188
+ // Delete a key
189
+ store.delete("number_value");
190
+ console.log("\nAfter delete 'number_value':");
191
+ console.log("All keys:", store.keys());
192
+
193
+ // Clone the store
194
+ const cloned = store.clone();
195
+ store.set("new_key", "only in original");
196
+ console.log("\nOriginal keys:", store.keys());
197
+ console.log("Cloned keys:", cloned.keys());
198
+
199
+ // Export to object
200
+ console.log("\nExport to object:", store.toObject());
201
+ }
202
+
203
+ // Run examples
204
+ storeDemo();
205
+
206
+ // Uncomment to run with actual API calls:
207
+ // main()
208
+ // .then(() => pipelineExample())
209
+ // .catch(console.error);
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Agent Definitions for Data Pipeline Example
3
+ */
4
+
5
+ import { ClaudeAgent } from "../../../lib/agents/anthropic/ClaudeAgent";
6
+
7
+ /**
8
+ * Creates the agents used in the data pipeline.
9
+ * Requires ANTHROPIC_API_KEY environment variable.
10
+ */
11
+ export function createPipelineAgents(apiKey: string) {
12
+ const analyzerAgent = new ClaudeAgent({
13
+ id: "analyzer",
14
+ name: "Data Analyzer",
15
+ description: `You are a data analysis agent. You receive information compiled from multiple sources
16
+ (internal databases, external web sources, vector databases, etc.).
17
+
18
+ Your job is to:
19
+ 1. Analyze and synthesize the information
20
+ 2. Note the source of each piece of information
21
+ 3. Identify any discrepancies between sources
22
+ 4. Highlight what's most important
23
+ 5. Flag any gaps in the data
24
+
25
+ Be objective and factual. If sources conflict, present both perspectives.`,
26
+ apiKey,
27
+ maxTokens: 1024,
28
+ });
29
+
30
+ const summarizerAgent = new ClaudeAgent({
31
+ id: "summarizer",
32
+ name: "Executive Summarizer",
33
+ description: `You create concise executive summaries.
34
+
35
+ Guidelines:
36
+ - Maximum 100 words
37
+ - Lead with the most important finding
38
+ - Use bullet points for key facts
39
+ - End with a clear recommendation or next step
40
+ - Be direct and actionable`,
41
+ apiKey,
42
+ maxTokens: 256,
43
+ });
44
+
45
+ const researchAgent = new ClaudeAgent({
46
+ id: "researcher",
47
+ name: "Research Agent",
48
+ description: `You are a research agent that synthesizes information from multiple data sources.
49
+ Given compiled research data, provide a comprehensive but focused analysis.
50
+ Structure your output clearly with sections for: Key Facts, Analysis, and Conclusions.`,
51
+ apiKey,
52
+ maxTokens: 1024,
53
+ });
54
+
55
+ return {
56
+ analyzerAgent,
57
+ summarizerAgent,
58
+ researchAgent,
59
+ };
60
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Data Fetcher Factories
3
+ *
4
+ * Demonstrates the factory pattern for creating data-fetching GraphNodes.
5
+ * Factories capture context (user permissions, tenant, config) at creation time,
6
+ * keeping the pipeline data flow simple (string -> string).
7
+ */
8
+
9
+ import { GraphNode } from "../../../lib/graph/AgentGraph";
10
+
11
+ // ============================================================================
12
+ // Types
13
+ // ============================================================================
14
+
15
+ export interface UserContext {
16
+ userId: string;
17
+ tenantId: string;
18
+ permissions: string[];
19
+ }
20
+
21
+ export interface DatabaseConfig {
22
+ connectionString?: string;
23
+ timeout?: number;
24
+ }
25
+
26
+ export interface ApiConfig {
27
+ baseUrl?: string;
28
+ apiKey?: string;
29
+ timeout?: number;
30
+ }
31
+
32
+ // ============================================================================
33
+ // Database Fetcher Factory
34
+ // ============================================================================
35
+
36
+ /**
37
+ * Creates a database fetcher with user context baked in.
38
+ * The returned GraphNode only needs a topic string - auth is handled internally.
39
+ */
40
+ export function createDatabaseFetcher(
41
+ userContext: UserContext,
42
+ config: DatabaseConfig = {}
43
+ ): GraphNode<string, string> {
44
+ // Simulated database with access control
45
+ const mockDatabase: Record<string, { data: string; requiredPermission: string }> = {
46
+ "penicillin": {
47
+ data: "Internal records: Alexander Fleming discovered penicillin in 1928 at St. Mary's Hospital London. Mass production began 1942. Patents filed 1940-1945. Estimated 200M lives saved.",
48
+ requiredPermission: "read:medical",
49
+ },
50
+ "quantum computing": {
51
+ data: "Internal records: Shor's algorithm (1994), Google quantum supremacy (2019), IBM 1000+ qubit processor (2023). Active research projects: QC-7, QC-12.",
52
+ requiredPermission: "read:tech",
53
+ },
54
+ "financials": {
55
+ data: "Q4 Revenue: $12.3M, YoY Growth: 23%, EBITDA margin: 18%. Confidential projections attached.",
56
+ requiredPermission: "read:finance",
57
+ },
58
+ "climate change": {
59
+ data: "Internal research: IPCC data analysis, Paris Agreement compliance tracking, carbon offset calculations for FY2023.",
60
+ requiredPermission: "read:research",
61
+ },
62
+ };
63
+
64
+ return {
65
+ name: `DatabaseFetcher[${userContext.userId}]`,
66
+ nodeType: "custom",
67
+ execute: async (topic: string) => {
68
+ console.log(` [DB] User ${userContext.userId} querying: "${topic}"`);
69
+ console.log(` [DB] Tenant: ${userContext.tenantId}, Permissions: ${userContext.permissions.join(", ")}`);
70
+
71
+ // Simulate database delay
72
+ await new Promise((resolve) => setTimeout(resolve, config.timeout ?? 100));
73
+
74
+ // Find matching records
75
+ const key = Object.keys(mockDatabase).find((k) =>
76
+ topic.toLowerCase().includes(k)
77
+ );
78
+
79
+ if (!key) {
80
+ console.log(` [DB] No records found`);
81
+ return `[Database] No internal records found for "${topic}".`;
82
+ }
83
+
84
+ const record = mockDatabase[key];
85
+
86
+ // Check permissions
87
+ if (!userContext.permissions.includes(record.requiredPermission)) {
88
+ console.log(` [DB] Access denied - requires ${record.requiredPermission}`);
89
+ return `[Database] Access denied. You don't have permission to access records about "${key}".`;
90
+ }
91
+
92
+ console.log(` [DB] Access granted - returning data`);
93
+ return `[Database] ${record.data}`;
94
+ },
95
+ };
96
+ }
97
+
98
+ // ============================================================================
99
+ // Web/API Fetcher Factory
100
+ // ============================================================================
101
+
102
+ /**
103
+ * Creates a web API fetcher with configuration baked in.
104
+ * In production, replace mock data with actual fetch() calls.
105
+ */
106
+ export function createWebFetcher(
107
+ config: ApiConfig = {}
108
+ ): GraphNode<string, string> {
109
+ // Simulated web API responses
110
+ const mockWebData: Record<string, string> = {
111
+ "penicillin": "Wikipedia: Penicillin is a group of antibiotics derived from Penicillium fungi. Discovery credited to Alexander Fleming (1928). Nobel Prize in Physiology/Medicine (1945) shared with Florey and Chain.",
112
+ "quantum computing": "Latest news: Quantum computing market expected to reach $65B by 2030. Recent breakthroughs in error correction. IBM, Google, and IonQ leading commercial efforts.",
113
+ "climate change": "Current data: 2023 confirmed as hottest year on record. Global average temperature 1.45°C above pre-industrial levels. COP28 agreements under implementation.",
114
+ };
115
+
116
+ return {
117
+ name: "WebFetcher",
118
+ nodeType: "custom",
119
+ execute: async (topic: string) => {
120
+ console.log(` [WEB] Fetching external data for: "${topic}"`);
121
+
122
+ // Simulate API call delay
123
+ await new Promise((resolve) => setTimeout(resolve, config.timeout ?? 150));
124
+
125
+ const key = Object.keys(mockWebData).find((k) =>
126
+ topic.toLowerCase().includes(k)
127
+ );
128
+
129
+ if (!key) {
130
+ console.log(` [WEB] No relevant data found`);
131
+ return `[Web] No relevant external data found for "${topic}".`;
132
+ }
133
+
134
+ console.log(` [WEB] Data retrieved`);
135
+ return `[Web] ${mockWebData[key]}`;
136
+ },
137
+ };
138
+ }
139
+
140
+ // ============================================================================
141
+ // Vector Database Fetcher Factory (placeholder for future)
142
+ // ============================================================================
143
+
144
+ /**
145
+ * Creates a vector database fetcher for semantic search.
146
+ * Placeholder for future vector DB integration.
147
+ */
148
+ export function createVectorDbFetcher(
149
+ userContext: UserContext,
150
+ config: { collection?: string; topK?: number } = {}
151
+ ): GraphNode<string, string> {
152
+ return {
153
+ name: `VectorDBFetcher[${config.collection ?? "default"}]`,
154
+ nodeType: "custom",
155
+ execute: async (topic: string) => {
156
+ console.log(` [VECTOR] Semantic search for: "${topic}"`);
157
+ console.log(` [VECTOR] Collection: ${config.collection ?? "default"}, TopK: ${config.topK ?? 5}`);
158
+
159
+ // Simulate vector search delay
160
+ await new Promise((resolve) => setTimeout(resolve, 200));
161
+
162
+ // Mock semantic search results
163
+ return `[VectorDB] Found 3 semantically similar documents for "${topic}". Top match (similarity: 0.89): "Related research document..."`;
164
+ },
165
+ };
166
+ }