### Running the Server Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Provides the necessary commands to install dependencies and start the FAF server development environment. ```bash cd examples/server-demo npm install npm run dev ``` -------------------------------- ### Run RAG Demo Application Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Steps to set up and run the RAG demo application. This involves navigating to the demo directory, installing dependencies, copying the environment configuration, editing it, and starting the development server. ```bash cd examples/rag-demo npm install cp .env.example .env # Edit .env with your configuration npm run dev ``` -------------------------------- ### Install FAF and LiteLLM Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Installs the Functional Agent Framework (FAF) using npm and sets up the LiteLLM proxy server using pip. Includes commands for starting the LiteLLM server with different configurations and setting API keys. ```bash npm install functional-agent-framework ``` ```bash pip install litellm ``` ```bash litellm --model gpt-3.5-turbo --port 4000 ``` ```bash export OPENAI_API_KEY=your_key_here litellm --model gpt-4o --port 4000 ``` ```bash litellm --config config.yaml --port 4000 ``` -------------------------------- ### Start PostgreSQL Server Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Commands to start a PostgreSQL server, either using Docker or local installation methods for macOS and Ubuntu, and create the necessary database. ```bash # Using Docker (recommended) docker run -d --name faf-postgres \ -e POSTGRES_PASSWORD=testpass \ -e POSTGRES_DB=faf_memory \ -p 5432:5432 \ postgres:15 # Or using local PostgreSQL brew install postgresql && brew services start postgresql # macOS createdb faf_memory # macOS sudo apt install postgresql postgresql-contrib # Ubuntu sudo systemctl start postgresql # Ubuntu sudo -u postgres createdb faf_memory # Ubuntu ``` -------------------------------- ### Development Server Demo Setup Source: https://github.com/xynehq/faf/blob/main/README.md Provides instructions for setting up and running the development server demo application. This includes navigating to the example directory, installing dependencies, and starting the development server. ```bash cd examples/server-demo npm install npm run dev ``` -------------------------------- ### Start Redis Server Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Commands to start a Redis server, either using Docker or local installation methods for macOS and Ubuntu. ```bash # Using Docker (recommended) docker run -d --name faf-redis -p 6379:6379 redis:alpine # Or using local Redis brew install redis && brew services start redis # macOS sudo apt install redis-server && sudo systemctl start redis-server # Ubuntu ``` -------------------------------- ### FAF Hello World Example Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md A TypeScript example demonstrating how to create a simple FAF agent with a greeting tool. It defines context, a tool with Zod schema validation, an agent with instructions, and sets up the execution environment with a LiteLLM provider. ```typescript import { run, Tool, Agent, makeLiteLLMProvider, generateRunId, generateTraceId } from 'functional-agent-framework'; import { z } from 'zod'; // 1. Define your context type type MyContext = { userId: string; permissions: string[]; }; // 2. Create a simple greeting tool const greetingTool: Tool<{ name: string }, MyContext> = { schema: { name: "greet", description: "Generate a personalized greeting", parameters: z.object({ name: z.string().describe("Name of the person to greet") }), }, execute: async (args, context) => { return `Hello, ${args.name}! I'm running on FAF. Your user ID is ${context.userId}.`; }, }; // 3. Define an agent const assistantAgent: Agent = { name: 'Assistant', instructions: () => 'You are a helpful assistant. Use the greeting tool when meeting new people.', tools: [greetingTool], }; // 4. Set up the execution environment async function runHelloWorld() { // Configure model provider const modelProvider = makeLiteLLMProvider('http://localhost:4000'); // Create agent registry const agentRegistry = new Map([['Assistant', assistantAgent]]); // Create initial state const initialState = { runId: generateRunId(), traceId: generateTraceId(), messages: [{ role: 'user' as const, content: 'Hi, my name is Alice' }], currentAgentName: 'Assistant', context: { userId: 'user123', permissions: ['user'] }, turnCount: 0, }; // Run the agent const result = await run(initialState, { agentRegistry, modelProvider, maxTurns: 5, onEvent: (event) => console.log('Event:', event.type), }); if (result.outcome.status === 'completed') { console.log('Response:', result.outcome.output); } else { console.error('Error:', result.outcome.error); } } runHelloWorld().catch(console.error); ``` -------------------------------- ### Development Server Setup Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Starts a development server for testing agents via HTTP, configuring it with agents, model provider, memory, and server-specific options like port and CORS. ```typescript import { runServer, makeLiteLLMProvider, createInMemoryProvider } from 'functional-agent-framework'; async function startDevServer() { const modelProvider = makeLiteLLMProvider('http://localhost:4000'); const memoryProvider = await createInMemoryProvider(); const server = await runServer( [assistantAgent, calculatorAgent], // Array of agents { modelProvider, maxTurns: 5, onEvent: (event) => console.log(event.type), memory: { provider: memoryProvider, autoStore: true, maxMessages: 100 } }, { port: 3000, host: '127.0.0.1', cors: true } ); console.log('Server running on http://localhost:3000'); } ``` -------------------------------- ### Start LiteLLM Proxy Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/README.md Instructions to install and start the LiteLLM proxy, a common requirement for using LLM services. This example uses OpenAI. ```bash # Install LiteLLM pip install litellm # Start proxy (example with OpenAI) litellm --model gpt-3.5-turbo --port 4000 ``` -------------------------------- ### Install and Start PostgreSQL (Ubuntu) Source: https://github.com/xynehq/faf/blob/main/docs/memory-system.md Installs PostgreSQL and related contrib packages, starts the service, and creates a database for FAF memory. ```bash sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql sudo -u postgres createdb faf_memory ``` -------------------------------- ### PostgreSQL Memory Provider Setup Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Installs PostgreSQL dependencies and configures the functional-agent-framework to use PostgreSQL for conversation persistence by setting environment variables and providing a PostgreSQL client. ```bash # Install PostgreSQL dependencies npm install pg @types/pg ``` ```typescript // Set environment variables process.env.FAF_MEMORY_TYPE = 'postgres'; process.env.FAF_POSTGRES_HOST = 'localhost'; process.env.FAF_POSTGRES_DB = 'faf_memory'; // Create PostgreSQL client const { Client } = await import('pg'); const postgresClient = new Client({ host: 'localhost', database: 'faf_memory', user: 'postgres', password: 'your_password' }); await postgresClient.connect(); // Create memory provider const memoryProvider = await createMemoryProviderFromEnv({ postgres: postgresClient }); ``` -------------------------------- ### Install and Start Redis (Ubuntu) Source: https://github.com/xynehq/faf/blob/main/docs/memory-system.md Installs Redis server using apt and starts the Redis service for local use. ```bash sudo apt install redis-server && sudo systemctl start redis-server ``` -------------------------------- ### Redis Memory Provider Setup Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Installs Redis dependencies and configures the functional-agent-framework to use Redis for conversation persistence by setting environment variables and providing a Redis client. ```bash # Install Redis dependencies npm install redis ``` ```typescript import { createMemoryProviderFromEnv } from 'functional-agent-framework'; // Set environment variables process.env.FAF_MEMORY_TYPE = 'redis'; process.env.FAF_REDIS_HOST = 'localhost'; process.env.FAF_REDIS_PORT = '6379'; // Create Redis client const { createClient } = await import('redis'); const redisClient = createClient({ url: 'redis://localhost:6379' }); await redisClient.connect(); // Create memory provider const memoryProvider = await createMemoryProviderFromEnv({ redis: redisClient }); ``` -------------------------------- ### Setup and Run RAG Demo Source: https://github.com/xynehq/faf/blob/main/README.md Commands to navigate to the RAG demo directory, install dependencies using npm, and start the development server. This is the initial setup for running the demo. ```bash cd examples/rag-demo npm install npm run dev ``` -------------------------------- ### Server Setup with Memory Configuration Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Demonstrates setting up the FAF server using environment variables for memory provider selection and configuring server-side options like maxTurns and event handling. ```typescript const memoryType = process.env.FAF_MEMORY_TYPE || 'memory'; const memoryProvider = await createMemoryProviderFromEnv(externalClients); const server = await runServer( [mathAgent, chatAgent, assistantAgent], { modelProvider, maxTurns: 5, onEvent: traceCollector.collect.bind(traceCollector), memory: { provider: memoryProvider, autoStore: true, // Automatically store conversation history maxMessages: 100 // Keep last 100 messages per conversation } }, { port: parseInt(process.env.PORT || '3000'), defaultMemoryProvider: memoryProvider } ); ``` -------------------------------- ### Copy Environment Configuration Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Copies the example environment file to be used for configuration. This file will be modified for different provider setups. ```bash cp .env.example .env ``` -------------------------------- ### Install and Start Redis (macOS) Source: https://github.com/xynehq/faf/blob/main/docs/memory-system.md Installs Redis using Homebrew and starts the Redis service for local use. ```bash brew install redis && brew services start redis ``` -------------------------------- ### Memory Provider Comparison Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Compares different memory providers (In-Memory, Redis, PostgreSQL) based on their best use cases, persistence, setup complexity, and scalability. ```APIDOC Memory Provider Comparison: Provider | Best For | Persistence | Setup Complexity | Scalability ----------------|--------------------------|--------------------------|------------------|------------ In-Memory | Development, testing | None (lost on restart) | None | Single instance Redis | Production, caching | Persistent | Moderate | High PostgreSQL | Production, complex queries | Full persistence | High | Very High ``` -------------------------------- ### FAF Quick Start Installation and Testing Source: https://github.com/xynehq/faf/blob/main/README.md Demonstrates the basic commands to install dependencies, build the project, and run tests for the Functional Agent Framework using npm. ```bash npm install npm run build npm test # Run tests ``` -------------------------------- ### Install and Start PostgreSQL (macOS) Source: https://github.com/xynehq/faf/blob/main/docs/memory-system.md Installs PostgreSQL using Homebrew and creates a database for FAF memory. ```bash brew install postgresql && brew services start postgresql createdb faf_memory ``` -------------------------------- ### LiteLLM Server Setup and Configuration Source: https://github.com/xynehq/faf/blob/main/docs/model-providers.md Provides instructions for setting up a LiteLLM server, including installation via pip, creating a configuration file (`litellm.yaml`) to define model mappings and API keys, and starting the server using the `litellm` command. ```bash pip install litellm[proxy] ``` ```yaml model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-sonnet litellm_params: model: anthropic/claude-3-sonnet-20240229 api_key: os.environ/ANTHROPIC_API_KEY - model_name: gemini-pro litellm_params: model: gemini/gemini-pro api_key: os.environ/GOOGLE_API_KEY ``` ```bash litellm --config litellm.yaml --port 4000 ``` -------------------------------- ### Basic Agent Setup Example Source: https://github.com/xynehq/faf/blob/main/docs/model-providers.md Demonstrates the fundamental setup for running an agent using the functional-agent-framework. It includes initializing a model provider (LiteLLM), defining a simple agent configuration, setting up run configuration, and executing the agent with an initial user message. ```typescript import 'dotenv/config'; import { run, RunConfig, RunState, createTraceId, createRunId, makeLiteLLMProvider } from 'functional-agent-framework'; // Set up model provider const modelProvider = makeLiteLLMProvider( process.env.LITELLM_URL!, process.env.LITELLM_API_KEY! ); // Define agent const agent = { name: 'Assistant', instructions: () => 'You are a helpful assistant.', modelConfig: { name: 'gpt-4o', temperature: 0.7, maxTokens: 1000 } }; // Run configuration const config: RunConfig = { agentRegistry: new Map([['Assistant', agent]]), modelProvider, maxTurns: 10 }; // Execute const result = await run({ runId: createRunId(crypto.randomUUID()), traceId: createTraceId(crypto.randomUUID()), messages: [{ role: 'user', content: 'Hello!' }], currentAgentName: 'Assistant', context: {}, turnCount: 0 }, config); ``` -------------------------------- ### Basic Agent Execution Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Shows how to run an agent using the functional-agent-framework, including setting up a model provider, agent registry, and initial state for the conversation. ```typescript import { run, makeLiteLLMProvider } from 'functional-agent-framework'; async function runAgent() { const modelProvider = makeLiteLLMProvider('http://localhost:4000'); const agentRegistry = new Map([['Assistant', assistantAgent]]); const initialState = { runId: generateRunId(), traceId: generateTraceId(), messages: [{ role: 'user', content: 'What is 15 * 7?' }], currentAgentName: 'Assistant', context: { userId: 'user123', permissions: ['user', 'calculator'] }, turnCount: 0, }; const result = await run(initialState, { agentRegistry, modelProvider, maxTurns: 10, modelOverride: 'gpt-4o', // Optional model override onEvent: (event) => { console.log(`[${event.type}]`, event.data); }, }); return result; } ``` -------------------------------- ### Run Basic FAF Server Setup (TypeScript) Source: https://github.com/xynehq/faf/blob/main/docs/server-api.md Demonstrates the basic setup for running a Functional Agent Framework (FAF) server using the `runServer` function. It shows how to import necessary components, define an agent, configure model and memory providers, and start the server. ```TypeScript import { runServer, makeLiteLLMProvider, createInMemoryProvider } from 'functional-agent-framework'; const myAgent = { name: 'MyAgent', instructions: () => 'You are a helpful assistant', tools: [] }; const modelProvider = makeLiteLLMProvider('http://localhost:4000'); const memoryProvider = createInMemoryProvider(); const server = await runServer( [myAgent], { modelProvider }, { port: 3000, defaultMemoryProvider: memoryProvider } ); ``` -------------------------------- ### In-Memory Memory System Setup Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Configures the functional-agent-framework to use an in-memory provider for conversation history, enabling automatic storage and setting a maximum number of messages. ```typescript import { createInMemoryProvider } from 'functional-agent-framework'; const memoryProvider = await createInMemoryProvider(); const config = { agentRegistry, modelProvider, memory: { provider: memoryProvider, autoStore: true, // Automatically store conversation history maxMessages: 100, // Keep last 100 messages per conversation }, conversationId: 'user-session-123', // Required for memory persistence }; ``` -------------------------------- ### Basic Chat Request Example Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Illustrates how to make a basic POST request to the `/chat` endpoint using curl, including a user message and agent specification. ```bash curl -X POST http://localhost:3000/chat \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "What is 15 * 7?"}], "agentName": "MathTutor", "context": {"userId": "demo", "permissions": ["user"]} }' ``` -------------------------------- ### Conversation with Memory Persistence Example Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Shows how to initiate and continue a conversation using a specific `conversationId`, demonstrating memory persistence across multiple requests. ```bash # Start conversation curl -X POST http://localhost:3000/chat \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "What is 15 * 7?"}], "conversationId": "my-conversation-1", "agentName": "MathTutor", "context": {"userId": "demo", "permissions": ["user"]} }' # Continue conversation (references previous calculation) curl -X POST http://localhost:3000/chat \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "What was my previous calculation?"}], "conversationId": "my-conversation-1", "agentName": "MathTutor", "context": {"userId": "demo", "permissions": ["user"]} }' ``` -------------------------------- ### Run FAF Server Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Starts the FAF development server using npm. This command is used after configuring the .env file for the desired memory provider. ```bash npm run dev ``` -------------------------------- ### Environment Variables for Configuration Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Details the environment variables required for configuring the LiteLLM client, the FAF server, and different memory providers (Redis, PostgreSQL). ```bash # Core LiteLLM configuration LITELLM_URL=http://localhost:4000 LITELLM_API_KEY=sk-your-api-key LITELLM_MODEL=gpt-3.5-turbo # Server configuration PORT=3000 # Memory provider selection FAF_MEMORY_TYPE=memory # or 'redis' or 'postgres' # Redis configuration (if using Redis) FAF_REDIS_HOST=localhost FAF_REDIS_PORT=6379 FAF_REDIS_PASSWORD=your-password FAF_REDIS_DB=0 # PostgreSQL configuration (if using PostgreSQL) FAF_POSTGRES_HOST=localhost FAF_POSTGRES_PORT=5432 FAF_POSTGRES_DB=faf_memory FAF_POSTGRES_USER=postgres FAF_POSTGRES_PASSWORD=your-password ``` -------------------------------- ### Agent Handoffs with `handoffTool` Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Shows how to implement agent handoffs in FAF using the `handoffTool`. This pattern allows an agent to delegate tasks to other specialized agents by listing them in the `handoffs` property. No additional setup is required for the tool itself. ```typescript import { handoffTool } from 'functional-agent-framework'; const triageAgent: Agent = { name: 'TriageAgent', instructions: () => 'Route requests to specialized agents based on the task.', tools: [handoffTool], handoffs: ['MathAgent', 'WeatherAgent'], // Allowed handoff targets }; // The handoff tool automatically transfers control // No additional setup required ``` -------------------------------- ### Redis Provider Setup Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Configures the .env file to use the Redis memory provider, specifying connection details like host, port, database, and a key prefix. ```bash # .env configuration FAF_MEMORY_TYPE=redis FAF_REDIS_HOST=localhost FAF_REDIS_PORT=6379 FAF_REDIS_DB=0 FAF_REDIS_PREFIX=faf:memory: ``` -------------------------------- ### Agent Execution with Tracing Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Configures agent execution to include tracing and observability by integrating a ConsoleTraceCollector to log events during the agent's run. ```typescript import { ConsoleTraceCollector } from 'functional-agent-framework'; const traceCollector = new ConsoleTraceCollector(); const config = { agentRegistry, modelProvider, maxTurns: 10, onEvent: traceCollector.collect.bind(traceCollector), }; ``` -------------------------------- ### RAG Demo Queries Source: https://github.com/xynehq/faf/blob/main/docs/examples.md An array of predefined queries used to demonstrate the RAG capabilities, including knowledge retrieval, conversation memory, and source attribution. ```typescript const demoQueries = [ "What is return URL?", "How do I integrate hypercheckout on android? Remember what we discussed earlier." ]; ``` -------------------------------- ### Server API Endpoints Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Lists the available RESTful API endpoints for the FAF server, detailing their HTTP methods, descriptions, and common use cases for monitoring and interaction. ```APIDOC API Endpoints: /health GET: Health check for server monitoring and load balancer checks. /agents GET: List available agents for discovery and frontend integration. /chat POST: General chat endpoint for agent-agnostic conversations. /agents/{name}/chat POST: Agent-specific endpoint for direct agent communication. /memory/health GET: Check the health status of the memory provider system. /conversations/:id GET: Retrieve a specific conversation by its ID. DELETE: Delete a specific conversation for cleanup purposes. ``` -------------------------------- ### FAF Memory Provider Setup Source: https://github.com/xynehq/faf/blob/main/docs/README.md Demonstrates how to create and configure memory providers for conversation persistence in FAF. Includes examples for in-memory, Redis, and PostgreSQL providers. ```typescript // Development const memory = await createInMemoryProvider(); // Production const memory = await createRedisProvider(config, redisClient); const memory = await createPostgresProvider(config, pgClient); ``` -------------------------------- ### Basic Chat Server Setup Source: https://github.com/xynehq/faf/blob/main/docs/server-api.md A minimal example of setting up a chat server using the `functional-agent-framework`. It configures a basic chat agent, a LiteLLM model provider, and an in-memory provider for conversation history. ```typescript import { runServer, makeLiteLLMProvider, createInMemoryProvider } from 'functional-agent-framework'; const chatAgent = { name: 'ChatBot', instructions: () => 'You are a helpful assistant', tools: [] }; async function startChatServer() { const server = await runServer( [chatAgent], { modelProvider: makeLiteLLMProvider('http://localhost:4000'), maxTurns: 10 }, { port: 3000, cors: true, defaultMemoryProvider: createInMemoryProvider() } ); console.log('Chat server running on http://localhost:3000'); } startChatServer().catch(console.error); ``` -------------------------------- ### Workflow Orchestration Configuration Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Sets up the configuration for running an agent workflow, including registering agents, specifying the model provider, setting maximum turns, and defining event handlers. ```typescript const workflowConfig: RunConfig = { agentRegistry: new Map([ ['TriageAgent', triageAgent], ['MathTutor', mathAgent], ['FileManager', fileAgent], ['RAGAgent', ragAgent] ]), modelProvider, maxTurns: 10, onEvent: (event) => { if (event.type === 'handoff') { console.log(`🔄 Handoff: ${event.data.from} → ${event.data.to}`); } } }; ``` -------------------------------- ### Build FAF Framework and Server Demo Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/test-memory-providers.md Commands to build the main FAF framework and the server demo using npm. This is a prerequisite for running the server. ```bash cd /Users/anurag.sharan/repos/faf && npm run build cd examples/server-demo && npm run build ``` -------------------------------- ### Custom Model Configurations Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Shows how to customize AI model parameters for agents, such as `temperature` for creativity and `maxTokens` for response length. Two examples are provided: a `CreativeAgent` with high temperature and a `FactualAgent` with low temperature for consistency. ```typescript const creativeAgent: Agent = { name: 'CreativeAgent', instructions: () => 'Be creative and imaginative in your responses.', tools: [], modelConfig: { temperature: 0.9, // High creativity maxTokens: 2000 } }; const factualAgent: Agent = { name: 'FactualAgent', instructions: () => 'Provide accurate, factual information only.', tools: [], modelConfig: { temperature: 0.1, // Low creativity, high consistency maxTokens: 500 } }; ``` -------------------------------- ### RAG Demo: Vertex AI Integration Overview Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Provides an overview of the RAG Demo, highlighting its integration with Google's Vertex AI, key features like streaming responses and source attribution, and its location. ```APIDOC RAG Demo: Vertex AI Integration Overview: Demonstrates real-world integration with Google's Vertex AI RAG system, showcasing streaming responses, source attribution, and performance metrics. Location: /Users/anurag.sharan/repos/faf/examples/rag-demo/ Key Features: - Real Vertex AI Integration: Uses Google's @google/genai SDK. - Streaming Responses: Real-time streaming from Vertex AI. - Source Attribution: Automatic grounding and citation. - Performance Metrics: Detailed timing and performance tracking. - Permission Control: Role-based access to RAG functionality. - Error Handling: Comprehensive error management. - Memory Integration: Conversation persistence with FAF memory providers. ``` -------------------------------- ### Custom Trace Collector Implementation Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Provides a custom trace collector that logs various events during agent execution, such as run starts, LLM calls, tool executions, handoffs, and run completions, with configurable log levels. ```typescript import { TraceEvent, ConsoleTraceCollector } from 'functional-agent-framework'; class CustomTraceCollector { constructor(private logLevel: 'debug' | 'info' | 'warn' | 'error' = 'info') {} collect(event: TraceEvent) { switch (event.type) { case 'run_start': console.log(`🚀 [${event.data.runId}] Starting conversation`); break; case 'llm_call_start': console.log(`🤖 [${event.data.agentName}] Calling ${event.data.model}`); break; case 'tool_call_start': console.log(`🔧 [${event.data.toolName}] Executing with args:`, event.data.args); break; case 'tool_call_end': const status = event.data.status || 'completed'; console.log(`✅ [${event.data.toolName}] ${status}`); break; case 'handoff': console.log(`🔄 Handoff: ${event.data.from} → ${event.data.to}`); break; case 'run_end': const outcome = event.data.outcome; if (outcome.status === 'completed') { console.log(`🎉 Conversation completed`); } else { console.error(`❌ Conversation failed:`, outcome.error); } break; } } } ``` -------------------------------- ### Environment Configuration (Bash) Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Provides essential environment variables for setting up and configuring the RAG system. This includes Google Cloud project details, LiteLLM proxy URL, API key, and the model to be used for RAG operations. ```bash # Google Cloud configuration GOOGLE_CLOUD_PROJECT=your-project-id # LiteLLM configuration LITELLM_URL=http://localhost:4000 LITELLM_API_KEY=sk-your-api-key LITELLM_MODEL=gemini-2.5-flash-lite ``` -------------------------------- ### Implement Robust Tool Error Handling Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Shows how to integrate standardized error handling into a tool using the `withErrorHandling` utility. This example covers input validation, permission checks, and general execution errors, returning structured `ToolResponse` objects. ```typescript import { withErrorHandling, ToolResponse, ToolErrorCodes } from 'functional-agent-framework'; const robustTool: Tool<{ input: string }, MyContext> = { schema: { name: "robust_tool", description: "A tool with proper error handling", parameters: z.object({ input: z.string() }), }, execute: withErrorHandling('robust_tool', async (args, context) => { // Validation if (!args.input.trim()) { return ToolResponse.validationError("Input cannot be empty"); } // Permission check if (!context.permissions.includes('required_permission')) { return ToolResponse.permissionDenied( "This tool requires special permissions", ['required_permission'] ); } // Business logic const result = processInput(args.input); // Assuming processInput is defined elsewhere return ToolResponse.success(result, { processingTime: Date.now(), inputLength: args.input.length }); }), }; ``` -------------------------------- ### Runtime Error Handling in FAF Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Demonstrates how to handle various runtime error types returned by FAF, such as MaxTurnsExceeded, ToolCallError, AgentNotFound, and InputGuardrailTripwire. It shows a TypeScript example using a switch statement to differentiate and process specific error conditions. ```typescript import { FAFErrorHandler } from 'functional-agent-framework'; if (result.outcome.status === 'error') { const error = result.outcome.error; switch (error._tag) { case 'MaxTurnsExceeded': console.log(`Exceeded ${error.turns} turns`); break; case 'ToolCallError': console.log(`Tool ${error.tool} failed: ${error.detail}`); break; case 'AgentNotFound': console.log(`Agent ${error.agentName} not found`); break; case 'InputGuardrailTripwire': console.log(`Input blocked: ${error.reason}`); break; // ... handle other error types } } ``` -------------------------------- ### Create Tool Debugging Wrapper (TypeScript) Source: https://github.com/xynehq/faf/blob/main/docs/examples.md This TypeScript code defines a higher-order function `createDebuggingWrapper` that enhances a `Tool` object by adding logging for execution start, arguments, context, results, and errors. It helps in debugging tool execution flow and performance. ```typescript const createDebuggingWrapper = (tool: Tool) => ({ ...tool, execute: async (args: A, context: Ctx) => { const startTime = Date.now(); console.log(`🔧 [${tool.schema.name}] Starting with:`, { args: JSON.stringify(args, null, 2), context: { userId: context.userId, permissions: context.permissions } }); try { const result = await tool.execute(args, context); const duration = Date.now() - startTime; console.log(`✅ [${tool.schema.name}] Completed in ${duration}ms`); console.log(`📤 [${tool.schema.name}] Result:`, result); return result; } catch (error) { const duration = Date.now() - startTime; console.error(`❌ [${tool.schema.name}] Failed after ${duration}ms:`, error); throw error; } } }); ``` -------------------------------- ### Node.js Application Dockerfile (Multi-stage) Source: https://github.com/xynehq/faf/blob/main/docs/deployment.md A multi-stage Dockerfile for building a production-ready Node.js application. It uses a builder stage for installing dependencies and compiling code, then copies only necessary artifacts to a minimal production image. Includes non-root user setup, signal handling with dumb-init, and a health check. ```dockerfile # Multi-stage build for production FROM node:18-alpine AS builder WORKDIR /app # Copy package files COPY package*.json ./ COPY tsconfig.json . # Install dependencies RUN npm ci --only=production && npm cache clean --force # Copy source code COPY src/ ./src/ # Build application RUN npm run build # Production stage FROM node:18-alpine AS production # Install dumb-init for proper signal handling RUN apk add --no-cache dumb-init # Create non-root user RUN addgroup -g 1001 -S faf && \ adduser -S faf -u 1001 WORKDIR /app # Copy built application and dependencies COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY --from=builder /app/package*.json . # Change ownership to non-root user RUN chown -R faf:faf /app USER faf # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD node -e "http.get('http://localhost:' + (process.env.PORT || 3000) + '/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))" # Expose port EXPOSE 3000 # Use dumb-init for proper signal handling ENTRYPOINT ["dumb-init", "--"] CMD ["node", "dist/index.js"] ``` -------------------------------- ### TypeScript Streaming Chat Tool Source: https://github.com/xynehq/faf/blob/main/docs/examples.md Defines a tool for initiating streaming chat conversations. It takes a message and session ID, starts a background streaming process, and returns a stream URL for real-time responses. Dependencies include 'eventsource' and internal utilities like 'generateStreamId', 'startStreamingResponse', 'createResponseStream', 'streamLLMResponse', and 'delay'. ```typescript import { EventSource } from 'eventsource'; const streamingChatTool: Tool = { schema: { name: "streaming_chat", description: "Initiate streaming conversation", parameters: z.object({ message: z.string(), sessionId: z.string() }) }, execute: async (args, context) => { const streamId = generateStreamId(); // Start streaming in background startStreamingResponse(streamId, args.message, context); return ToolResponse.success('Streaming started', { streamId, streamUrl: `/stream/${streamId}`, message: 'Connect to stream URL for real-time responses' }); } }; async function startStreamingResponse(streamId: string, message: string, context: StreamingContext) { const stream = createResponseStream(streamId); try { stream.write({ type: 'start', data: { streamId } }); // Simulate streaming LLM response const response = await streamLLMResponse(message); for await (const chunk of response) { stream.write({ type: 'chunk', data: { content: chunk } }); await delay(50); // Simulate realistic streaming delay } stream.write({ type: 'end', data: { completed: true } }); } catch (error) { stream.write({ type: 'error', data: { error: error.message } }); } finally { stream.close(); } } ``` -------------------------------- ### Run Development Server Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/README.md Starts the FAF development server using npm. The server will be accessible at http://localhost:3000 by default. ```bash npm run dev ``` -------------------------------- ### Run the Vertex AI RAG Demo Source: https://github.com/xynehq/faf/blob/main/examples/rag-demo/README.md Provides instructions on how to run the demo application after setting up dependencies and environment variables. It includes commands for direct execution (`npm run dev`) and for building and then starting the application. ```bash # Make sure you have your .env file configured cp .env.example .env # Edit .env with your actual values # Run the demo npm run dev # Or with TypeScript compilation npm run build npm start ``` -------------------------------- ### Server API Endpoints and Usage Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Defines the available server API endpoints for the FAF framework, including health checks, agent listing, and chat functionalities. It also provides an example of how to interact with the general chat endpoint using cURL, specifying messages, agent name, conversation ID, and context. ```APIDOC Server API Endpoints: - GET /health: Health check for the server. - GET /agents: Lists all available agents. - POST /chat: General chat endpoint for interacting with agents. - POST /agents/{name}/chat: Agent-specific chat endpoint. - GET /memory/health: Health check for the memory system. Example API Usage (cURL): ```bash # Chat with an agent curl -X POST http://localhost:3000/chat \ -H "Content-Type: json" \ -d '{ "messages": [{"role": "user", "content": "What is 15 * 7?"}], "agentName": "SmartAssistant", "conversationId": "session-123", "context": {"userId": "user123", "permissions": ["user", "calculator"]} }' ``` ``` -------------------------------- ### Start PostgreSQL Server Source: https://github.com/xynehq/faf/blob/main/examples/server-demo/README.md Commands to start a PostgreSQL server, either via Docker, Homebrew (macOS), or apt (Ubuntu). PostgreSQL is used for persistent conversation storage. ```bash # Using Docker docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password -e POSTGRES_DB=faf_memory postgres:15 # Or install locally (macOS) brew install postgresql brew services start postgresql createdb faf_memory # Or install locally (Ubuntu) sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql sudo -u postgres createdb faf_memory ``` -------------------------------- ### Create a Multi-Tool Agent with TypeScript Source: https://github.com/xynehq/faf/blob/main/docs/getting-started.md Demonstrates creating a sophisticated agent capable of using multiple tools, including a calculator and a weather tool. It shows how to define tool schemas, implement execution logic with context, and configure the agent's instructions and model settings. ```typescript import { Tool, Agent, ToolResponse, ToolErrorCodes, withErrorHandling } from 'functional-agent-framework'; type MyContext = { userId: string; permissions: string[]; }; // Math calculation tool with error handling const calculatorTool: Tool<{ expression: string }, MyContext> = { schema: { name: "calculate", description: "Perform mathematical calculations", parameters: z.object({ expression: z.string().describe("Math expression to evaluate (e.g., '2 + 2', '10 * 5')") }), }, execute: withErrorHandling('calculate', async (args, context) => { // Input validation const sanitized = args.expression.replace(/[^0-9+\-*/().\s]/g, ''); if (sanitized !== args.expression) { return ToolResponse.validationError( "Invalid characters in expression. Only numbers, +, -, *, /, (, ), and spaces are allowed.", { originalExpression: args.expression } ); } try { const result = eval(sanitized); return ToolResponse.success(`${args.expression} = ${result}`, { originalExpression: args.expression, result, calculationType: 'arithmetic' }); } catch (evalError) { return ToolResponse.error( ToolErrorCodes.EXECUTION_FAILED, `Failed to evaluate expression: ${evalError instanceof Error ? evalError.message : 'Unknown error'}`, { expression: args.expression } ); } }), }; // Weather tool (mock implementation) const weatherTool: Tool<{ location: string }, MyContext> = { schema: { name: "get_weather", description: "Get current weather information for a location", parameters: z.object({ location: z.string().describe("City name or location") }), }, execute: async (args, context) => { // Check permissions if (!context.permissions.includes('weather_access')) { return ToolResponse.permissionDenied( "Weather access requires 'weather_access' permission", ['weather_access'] ); } // Mock weather data const weatherData = { location: args.location, temperature: Math.floor(Math.random() * 30) + 10, condition: ['sunny', 'cloudy', 'rainy'][Math.floor(Math.random() * 3)], humidity: Math.floor(Math.random() * 100) }; return ToolResponse.success( `Weather in ${weatherData.location}: ${weatherData.temperature}°C, ${weatherData.condition}, ${weatherData.humidity}% humidity`, weatherData ); }, }; // Create a multi-tool agent const assistantAgent: Agent = { name: 'SmartAssistant', instructions: (state) => `You are a helpful assistant with access to calculation and weather tools. Current user: ${state.context.userId} User permissions: ${state.context.permissions.join(', ')} You can: - Perform mathematical calculations using the calculator tool - Get weather information (if user has weather_access permission) - Engage in helpful conversation Always use the appropriate tools when the user asks for calculations or weather information.`, tools: [calculatorTool, weatherTool], modelConfig: { temperature: 0.1, // Lower temperature for more consistent responses maxTokens: 1000 } }; ```