### start(config, functions) Source: https://docs.microfn.dev/modules/agent Start an agent execution asynchronously and return immediately with an execution ID. The agent uses the provided functions to accomplish the specified objective. ```APIDOC ## start(config, functions) ### Description Start an agent execution asynchronously and return immediately. ### Parameters #### config (AgentConfig) - Required Configuration object with agent objective - **objective** (string) - Required - What the agent should accomplish #### functions (FunctionConfig[]) - Required Array of functions the agent can use - **function** (string | Function) - Required - Function reference by name or direct import - **description** (string) - Optional - When to use this function (hint for the LLM) ### Returns `Promise<{ executionId: string }>` - Object containing the execution ID for status tracking ### Throws - `Error` if agent config is invalid - `Error` if no functions are provided - `Error` if the request fails ### Request Example ```javascript import agent from "@microfn/agent"; const { executionId } = await agent.start({ objective: "Research the latest developments in quantum computing and summarize the top 3 breakthroughs" }, [ { function: "myusername/search-web", description: "Searches the web for information" }, { function: "myusername/extract-article", description: "Extracts content from a web article" }, { function: "myusername/summarize-text", description: "Summarizes long text content" } ]); ``` ### Response Example ```json { "executionId": "exec_123abc456def" } ``` ``` -------------------------------- ### Minimal TypeScript Function for Microfn Source: https://docs.microfn.dev/triggers/webhook An example of a minimal function entrypoint for microfn. It imports the 'kv' module (though not used in this minimal example) and logs the input before returning a stringified version of it. This serves as a basic template for new functions. ```typescript import kv from "@microfn/kv"; // An exported main function is your entrypoint export async function main(input: any) { console.log("processing", input); // const value = await kv.get("my-key"); return "hello " + JSON.stringify(input); } ``` -------------------------------- ### Translate Text with AI Source: https://docs.microfn.dev/modules/ai Demonstrates translating text to a target language using `askAi`. It includes a `systemPrompt` to guide the AI as a professional translator and uses `temperature` for translation accuracy. ```javascript import { askAi } from "@microfn/ai"; export default async function main({ text, targetLanguage }) { const translation = await askAi( `Translate to ${targetLanguage}: ${text}`, { systemPrompt: "You are a professional translator. Provide accurate, natural-sounding translations.", temperature: 0.2 } ); return { original: text, translated: translation }; } ``` -------------------------------- ### Manage Configuration via API Source: https://docs.microfn.dev/configuration Provides examples of using cURL commands to programmatically manage Microfn configuration. It shows how to add secrets and packages to a workspace. This method allows for automated configuration management. ```bash # Add a secret curl -X POST https://microfn.dev/api/workspaces/username/workspace/secrets \ -H "Authorization: Bearer TOKEN" \ -d '{"key": "API_KEY", "value": "secret-value"}' # Add a package curl -X POST https://microfn.dev/api/workspaces/username/workspace/packages \ -H "Authorization: Bearer TOKEN" \ -d '{"name": "lodash", "version": "4.17.21"}' ``` -------------------------------- ### Initialize Complex Workflow Agent with Microfn Source: https://docs.microfn.dev/modules/agent Creates and starts a complex workflow agent with a multi-step objective for project setup. The agent receives project requirements as input and orchestrates multiple functions including requirements analysis, project planning, repository setup, boilerplate generation, documentation creation, CI/CD configuration, and testing. Returns an execution ID for tracking agent progress. ```TypeScript import agent from "@microfn/agent"; export default async function main(input: { projectRequirements: string; }) { const { executionId } = await agent.start({ objective: `Based on these requirements: ${input.projectRequirements} 1. Create a project plan 2. Set up the development environment 3. Generate initial code structure 4. Create documentation 5. Set up CI/CD pipeline` }, [ { function: "myusername/analyze-requirements", description: "Analyzes project requirements" }, { function: "myusername/create-project-plan", description: "Creates detailed project plan" }, { function: "myusername/setup-repository", description: "Sets up git repository" }, { function: "myusername/generate-boilerplate", description: "Generates project boilerplate code" }, { function: "myusername/create-documentation", description: "Creates project documentation" }, { function: "myusername/setup-ci-cd", description: "Sets up CI/CD pipeline" }, { function: "myusername/run-tests", description: "Runs initial tests" } ]); return { executionId, message: "Project setup agent started" }; } ``` -------------------------------- ### Generate Code with AI Source: https://docs.microfn.dev/modules/ai An example of using `askAi` to generate code snippets based on a description and specified programming language. It employs a `systemPrompt` for expert programmer behavior and adjusts `temperature` for code quality. ```javascript import { askAi } from "@microfn/ai"; export default async function main({ description, language }) { const code = await askAi( `Write a ${language} function that: ${description}`, { systemPrompt: "You are an expert programmer. Generate clean, efficient, well-commented code.", temperature: 0.4 } ); return { description, code }; } ``` -------------------------------- ### Calling Microfn Webhook with String and JSON Payloads using cURL Source: https://docs.microfn.dev/triggers/webhook Examples using cURL to demonstrate how to call a microfn webhook endpoint. It shows how a raw string body is wrapped into a JSON object `{ "input": "..." }` on the server-side, while a pre-formatted JSON body is passed through directly. ```bash # String body becomes { "input": "hello" } curl -X POST https://microfn.dev/run/david/test-func -d 'hello' # -> "hello {"input":"hello"}" # JSON body is passed through as-is curl -X POST https://microfn.dev/run/david/test-func -d '{"Hello":"foo"}' # -> "hello {"Hello":"foo"}" ``` -------------------------------- ### Basic Microfn Module Usage Example (TypeScript) Source: https://docs.microfn.dev/modules Demonstrates how to use multiple Microfn modules (@microfn/kv, @microfn/ai, @microfn/secret) together in a single function. It retrieves an API key from secrets, checks for cached data using KV storage, generates new data with AI if not cached, and then caches the result. This example highlights the seamless integration of different modules for a common task. ```typescript import kv from "@microfn/kv"; import { askAi } from "@microfn/ai"; import secret from "@microfn/secret"; export default async function main(input: any) { // Get API configuration from secrets const apiKey = await secret.get("API_KEY"); // Check if we have cached data const cacheKey = `data:${input.id}`; let data = await kv.get(cacheKey); if (!data) { // No cache, generate new data with AI data = await askAi(`Generate data for ID: ${input.id}`); // Cache for future use await kv.set(cacheKey, data); } return { data, cached: !!data }; } ``` -------------------------------- ### Organize Configuration Variables Source: https://docs.microfn.dev/configuration Provides examples of grouping related configuration variables into distinct objects for better organization and readability. It shows how to structure database and API configurations, fetching necessary secrets and parsing values as needed. This improves maintainability of complex configurations. ```javascript // Group related configuration const dbConfig = { host: await secret.get("DB_HOST"), port: await secret.get("DB_PORT", "5432"), name: await secret.get("DB_NAME"), user: await secret.get("DB_USER"), password: await secret.getRequired("DB_PASSWORD") }; const apiConfig = { key: await secret.getRequired("API_KEY"), url: await secret.get("API_URL"), timeout: parseInt(await secret.get("API_TIMEOUT", "5000")) }; ``` -------------------------------- ### TypeScript Function as Simple HTTP Proxy (GET JSON) Source: https://docs.microfn.dev/triggers/webhook This TypeScript function acts as a simple HTTP proxy. It takes a URL from the input (defaulting to GitHub's rate limit API) and makes a GET request to it, setting a 'User-Agent' header. It then returns the JSON response from the fetched URL. ```typescript // 3) Simple HTTP proxy (GET JSON) export async function main(input: any) { const url = input?.url ?? "https://api.github.com/rate_limit"; const res = await fetch(url, { headers: { "User-Agent": "microfn" } }); return await res.json(); } ``` -------------------------------- ### Summarize Content with AI Source: https://docs.microfn.dev/modules/ai This example shows how to use the `askAi` function to summarize provided article content into three bullet points. It utilizes the `temperature` option to control the creativity of the summary. ```javascript import { askAi } from "@microfn/ai"; export default async function main({ articleContent }) { const summary = await askAi( `Summarize this article in 3 bullet points: ${articleContent}`, { temperature: 0.3 } ); return { summary }; } ``` -------------------------------- ### Basic Set and Get Operations with @microfn/kv Source: https://docs.microfn.dev/modules/kv Demonstrates fundamental key-value operations: writing data with kv.set() and reading data with kv.get(). Both operations are asynchronous and return promises that must be awaited. ```javascript // Write to the key-value store await kv.set("my-key", { message: "Hello World" }); // Read from the key-value store const value = await kv.get("my-key"); ``` -------------------------------- ### Start Agent Execution Source: https://docs.microfn.dev/modules/agent Initialize an asynchronous agent execution with a specific objective and array of available functions. Returns immediately with an execution ID that can be used to track progress. The agent uses the provided functions to accomplish its objective. ```javascript import agent from "@microfn/agent"; export default async function main() { const { executionId } = await agent.start({ objective: "Research the latest developments in quantum computing and summarize the top 3 breakthroughs" }, [ { function: "myusername/search-web", description: "Searches the web for information" }, { function: "myusername/extract-article", description: "Extracts content from a web article" }, { function: "myusername/summarize-text", description: "Summarizes long text content" } ]); return { executionId, message: "Agent started. Check status with execution ID." }; } ``` -------------------------------- ### Get Secrets with @microfn/secret Source: https://docs.microfn.dev/configuration Demonstrates how to retrieve secrets using the @microfn/secret module. It shows getting a required secret and an optional secret with a default value. Secrets are stored encrypted and accessed securely. ```javascript import secret from "@microfn/secret"; const apiKey = await secret.getRequired("API_KEY"); const dbUrl = await secret.get("DATABASE_URL", "localhost:5432"); ``` -------------------------------- ### TypeScript Function for Tiny Counter using KV Source: https://docs.microfn.dev/triggers/webhook An example of a TypeScript function using microfn's KV (Key-Value) store to implement a simple counter. It dynamically generates a key based on the input route (or defaults to 'default') and increments a hit count stored in the KV. It returns the route and the updated hit count. ```typescript // 2) Tiny counter using KV import kv from "@microfn/kv"; export async function main(input: any) { const key = `hits:${input?.route ?? "default"}`; const hits = (await kv.get(key)) ?? 0; await kv.set(key, hits + 1); return { route: input?.route ?? "default", hits: hits + 1 }; } ``` -------------------------------- ### Async/Await Usage with Multiple Microfn Modules (TypeScript) Source: https://docs.microfn.dev/modules Shows how to leverage modern async/await syntax to concurrently execute operations using different Microfn modules. This example uses `Promise.all` to fetch data from KV storage and generate text with AI simultaneously, improving function performance. ```typescript export default async function main() { const results = await Promise.all([ kv.get("key1"), kv.get("key2"), askAi("Generate a summary") ]); return results; } ``` -------------------------------- ### Accessing Secrets with @microfn/secret Module Source: https://docs.microfn.dev/configuration/secrets Demonstrates how to retrieve secrets using the '@microfn/secret' module. It shows functions to get secrets with or without default values, get required secrets that must exist, check for the existence of a secret, and retrieve all secrets with a specific prefix. Secrets are injected as environment variables with the 'SECRET_' prefix at runtime. ```javascript import secret from "@microfn/secret"; export default async function main() { // Get a secret (returns undefined if not found) const apiKey = await secret.get("API_KEY"); // Get with default value const timeout = await secret.get("TIMEOUT", "5000"); // Get required secret (throws if not found) const dbUrl = await secret.getRequired("DATABASE_URL"); // Check if secret exists const hasStripeKey = await secret.has("STRIPE_KEY"); // Get all secrets with prefix const awsSecrets = await secret.getWithPrefix("AWS_"); return { configured: true }; } ``` -------------------------------- ### Database Connection using MySQL2 with Secrets Source: https://docs.microfn.dev/configuration/secrets Demonstrates establishing a MySQL database connection by retrieving credentials from Microfn secrets. It uses `secret.getRequired` for essential parameters like host, user, password, and database name, and `secret.get` with a default for the port. The example connects, executes a query, and then closes the connection. ```javascript import secret from "@microfn/secret"; import { createConnection } from 'mysql2/promise'; export default async function main(input) { // Build connection string from secrets const connection = await createConnection({ host: await secret.getRequired("DB_HOST"), port: parseInt(await secret.get("DB_PORT", "3306")), user: await secret.getRequired("DB_USER"), password: await secret.getRequired("DB_PASSWORD"), database: await secret.getRequired("DB_NAME") }); const [rows] = await connection.execute( 'SELECT * FROM users WHERE id = ?', [input.userId] ); await connection.end(); return { user: rows[0] }; } ``` -------------------------------- ### Build Custom Service Client Source: https://docs.microfn.dev/integrations This JavaScript example shows how to build a custom service client to interact with any external API. It uses an API key stored as a secret and provides a `request` method for making POST requests to a specified endpoint. It includes basic error handling via the response JSON. ```javascript import secret from "@microfn/secret"; class CustomServiceClient { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = "https://api.customservice.com"; } async request(endpoint, data) { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); return await response.json(); } } export default async function main(input) { const apiKey = await secret.getRequired("CUSTOM_SERVICE_KEY"); const client = new CustomServiceClient(apiKey); const result = await client.request('/process', input); return result; } ``` -------------------------------- ### Use API Key with @microfn/secret Source: https://docs.microfn.dev/modules/secret This example shows how to securely fetch an API key using `secret.get` and use it to authenticate an API request. It includes a check to ensure the API key is configured before making the request. ```javascript import secret from "@microfn/secret"; export default async function main() { const apiKey = await secret.get("STRIPE_API_KEY"); if (!apiKey) { return { error: "API key not configured." }; } const response = await fetch("https://api.stripe.com/v1/charges", { headers: { Authorization: `Bearer ${apiKey}` } }); return { success: response.ok }; } ``` -------------------------------- ### Customer Support Agent - TypeScript Source: https://docs.microfn.dev/modules/agent Starts a customer support agent to assist a customer with a specific issue. It outlines the objective and the functions used to retrieve customer information, check history, search knowledge base, create tickets, and send emails. ```typescript import agent from "@microfn/agent"; export default async function main(input: { customerId: string; issue: string; }) { const { executionId } = await agent.start({ objective: `Help customer ${input.customerId} resolve: ${input.issue}. Check their account history, identify the problem, and provide a solution or escalate if needed.` }, [ { function: "myusername/get-customer-info", description: "Retrieves customer account information" }, { function: "myusername/check-order-history", description: "Gets customer's order history" }, { function: "myusername/search-knowledge-base", description: "Searches support documentation for solutions" }, { function: "myusername/create-support-ticket", description: "Creates a support ticket for escalation" }, { function: "myusername/send-email", description: "Sends email to customer" } ]); return { executionId, customerId: input.customerId, issueLogged: true }; } ``` -------------------------------- ### Import AI Agent Module Source: https://docs.microfn.dev/modules/agent Import the agent module or specific functions from @microfn/agent. The module is automatically available in all Microfn functions without requiring separate installation. ```javascript import agent from "@microfn/agent"; // or import { start, getStatus } from "@microfn/agent"; ``` -------------------------------- ### getStatus(executionId) Source: https://docs.microfn.dev/modules/agent Get the current status of an asynchronous agent execution. Returns the execution status, progress, and final result when completed. ```APIDOC ## getStatus(executionId) ### Description Get the current status of an asynchronous agent execution. ### Parameters #### executionId (string) - Required The execution ID returned from start() ### Returns `Promise` - The agent status object with the following properties: - **status** (string) - Current execution status: 'waiting' | 'running' | 'completed' | 'failed' - **progress** (any) - Optional - Intermediate steps or logs - **result** (any) - Optional - The final result upon completion ### Throws - `Error` if execution ID is invalid - `Error` if the status request fails ### Request Example ```javascript import agent from "@microfn/agent"; const status = await agent.getStatus("exec_123abc456def"); ``` ### Response Example - Completed ```json { "status": "completed", "result": { "breakthroughs": [ "Quantum error correction advances", "New qubit design", "Enhanced quantum algorithms" ] } } ``` ### Response Example - Running ```json { "status": "running", "progress": [ "Searching for quantum computing articles", "Extracting content from 5 sources" ] } ``` ### Response Example - Failed ```json { "status": "failed", "progress": "Unable to access search function" } ``` ``` -------------------------------- ### API Integration using OpenAI with Secrets Source: https://docs.microfn.dev/configuration/secrets This example shows how to integrate with the OpenAI API by securely fetching an API key from Microfn secrets. It uses `secret.getRequired` to ensure the 'OPENAI_API_KEY' is available before making a POST request to the OpenAI completions endpoint. The function takes a prompt from the input and returns the API response. ```javascript import secret from "@microfn/secret"; export default async function main(input) { const apiKey = await secret.getRequired("OPENAI_API_KEY"); const response = await fetch("https://api.openai.com/v1/completions", { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [{ role: "user", content: input.prompt }] }) }); return await response.json(); } ``` -------------------------------- ### Microfn: Store Data and Use AI in a Serverless Function (TypeScript) Source: https://docs.microfn.dev/index This example demonstrates a basic Microfn function written in TypeScript. It utilizes the `@microfn/kv` module to store data persistently across function executions and the `@microfn/ai` module to process input using AI. The function takes any input, stores a timestamp, analyzes the input with AI, and returns the timestamp along with the AI analysis. ```typescript import kv from "@microfn/kv"; import { askAi } from "@microfn/ai"; export default async function main(input: any) { // Store data that persists across executions await kv.set("lastRequest", new Date().toISOString()); // Use AI to process input const analysis = await askAi(`Analyze this data: ${JSON.stringify(input)}`); return { timestamp: await kv.get("lastRequest"), analysis }; } ``` -------------------------------- ### Error Handling for Secrets Management (TypeScript) Source: https://docs.microfn.dev/modules Demonstrates robust error handling when accessing secrets using the @microfn/secret module. The example uses a `try-catch` block to gracefully manage potential errors, such as a missing required secret, providing clear feedback. ```typescript try { const required = await secret.getRequired("REQUIRED_SECRET"); } catch (error) { // Error: Required secret REQUIRED_SECRET is not set } ``` -------------------------------- ### Email Trigger Function (JavaScript) Source: https://docs.microfn.dev/triggers Example of a JavaScript function triggered by an incoming email. The function receives email data, including sender, subject, and body, for processing. ```javascript // Email sent to: ws-abc123xyz@mail.microfn.dev export default async function main(input) { // input contains email data const { from, subject, body } = input; await processEmail(from, subject, body); return { processed: true }; } ``` -------------------------------- ### Monitoring Agent Execution - TypeScript Source: https://docs.microfn.dev/modules/agent Manages the lifecycle of agent executions, allowing for starting new agents and checking the status of existing ones. It integrates with both the agent system and a key-value store for persisting execution metadata. ```typescript import agent from "@microfn/agent"; import kv from "@microfn/kv"; export default async function main(input: { action: "start" | "check"; executionId?: string; objective?: string; }) { if (input.action === "start") { const { executionId } = await agent.start({ objective: input.objective! }, [ // ... function configurations ]); // Store execution metadata await kv.set(`agent:${executionId}`, { startTime: new Date(), objective: input.objective, status: "started" }); return { executionId }; } if (input.action === "check" && input.executionId) { const status = await agent.getStatus(input.executionId); const metadata = await kv.get(`agent:${input.executionId}`); // Update metadata await kv.set(`agent:${input.executionId}`, { ...metadata, status: status.status, lastChecked: new Date(), result: status.result }); return { ...status, metadata }; } return { error: "Invalid action or missing parameters" }; } ``` -------------------------------- ### Function with Multiple Trigger Handling (JavaScript) Source: https://docs.microfn.dev/triggers Example of a JavaScript function designed to handle multiple trigger types (webhook, cron, email) by inspecting an input property. This allows a single function to adapt its behavior based on how it was invoked. ```javascript export default async function main(input) { // Determine trigger source const triggerSource = input.triggerSource || "webhook"; switch (triggerSource) { case "cron": // Scheduled execution logic return await handleScheduledRun(); case "email": // Email trigger logic return await processEmail(input); default: // Webhook logic return await handleWebhook(input); } } ``` -------------------------------- ### Dual Handler with Cron Integration - TypeScript Source: https://docs.microfn.dev/triggers/cron Complete example demonstrating both manual invocation via `main()` and scheduled execution via `cron()`. Shows integration with @microfn/fn library to call other functions from within the cron handler, enabling cross-function orchestration for automated workflows. ```typescript import fn from "@microfn/fn"; // Welcome to Microfn! // This is a serverless function that runs in the cloud. // Export a main function that takes { input: data } and returns any value. // Strings/numbers are returned as-is, objects/arrays are JSON serialized. export async function main({ input }) { return { message: "Hello from Microfn!", timestamp: new Date().toISOString(), receivedInput: input }; } export async function cron(data) { // handle cron trigger console.log("cron triggered"); const discordPayload = { channelId: "1365582079387107400", content: "corn 🌽" }; const discordResult = await fn.executeFunction("david/send-discord-message", discordPayload); return "corn"; } ``` -------------------------------- ### TypeScript Function with Basic Input Validation Source: https://docs.microfn.dev/triggers/webhook This TypeScript function demonstrates basic input validation for microfn. It checks if the input is provided; if not, it returns an error object. Otherwise, it returns a success object along with the provided input. ```typescript // 1) Echo with basic validation export async function main(input: any) { if (!input) return { error: "missing input" }; return { ok: true, input }; } ``` -------------------------------- ### Import and Use NPM Package Automatically (JavaScript) Source: https://docs.microfn.dev/configuration/packages Demonstrates how to import an NPM package like 'lodash' directly in your serverless function. Microfn automatically detects the import and installs the latest version during deployment. The function processes an input array by sorting items based on priority. ```javascript import _ from 'lodash'; export default async function main(input) { const sorted = _.orderBy(input.items, ['priority'], ['desc']); return { processed: sorted }; } ``` -------------------------------- ### Microfn Handler with Email Trigger (JavaScript) Source: https://docs.microfn.dev/triggers/email An example Microfn function handler in JavaScript that exports both a `main` function for general use and an `email` function specifically for handling email triggers. The `email` function logs received data, demonstrating how to process incoming emails. ```javascript // Welcome to Microfn! // This is a serverless function that runs in the cloud. // Export a main function that takes { input: data } and returns any value. // Strings/numbers are returned as-is, objects/arrays are JSON serialized. export async function main({ input }) { return { message: "Hello from Microfn!", timestamp: new Date().toISOString(), receivedInput: input }; } export async function email(data) { // handle email trigger console.log("email received"); console.log(data); } ``` -------------------------------- ### Manage Feature Flags with @microfn/secret Source: https://docs.microfn.dev/modules/secret This example shows how to manage feature flags using secrets. It retrieves a feature flag value (defaulting to 'false') and checks if it's 'true' to conditionally enable new features, allowing for in-app feature toggling without code redeployment. ```javascript import secret from "@microfn/secret"; export default async function main() { const newSearchEnabled = await secret.get("FEATURE_NEW_SEARCH", "false") === "true"; if (newSearchEnabled) { // run new search logic return { feature: "new-search" }; } else { // run old search logic return { feature: "old-search" }; } } ``` -------------------------------- ### Basic AI Query Source: https://docs.microfn.dev/modules/ai A quick snippet demonstrating how to send a query to the AI and receive a response. It uses the `askAi` function and returns both the original query and the AI's response. ```javascript async function getResponse({ query }) { const response = await askAi(query); return { query, response }; } ``` -------------------------------- ### Define Configuration with Infrastructure as Code Source: https://docs.microfn.dev/configuration Shows how to define secrets and NPM packages as code using a JavaScript configuration object. This approach enables managing configuration alongside your function code. It supports specifying keys, descriptions, and package versions. ```javascript export const config = { secrets: [ { key: "API_KEY", description: "Main API key" }, { key: "DATABASE_URL", description: "Database connection" } ], packages: [ { name: "lodash", version: "^4.17.21" }, { name: "axios", version: "^1.0.0" } ] }; ``` -------------------------------- ### Integrate Agent with KV, AI, and Function Modules Source: https://docs.microfn.dev/modules/agent Demonstrates multi-module integration pattern combining agent orchestration with key-value storage, AI enhancement, and function logging. Retrieves agent configuration from KV store, uses AI to enhance the task objective, executes the agent with the improved objective, and logs execution details. Stores execution references in KV for later retrieval and audit tracking. ```TypeScript import agent from "@microfn/agent"; import kv from "@microfn/kv"; import { askAi } from "@microfn/ai"; import fn from "@microfn/fn"; export default async function main(input: { task: string }) { // Get agent configuration from KV const agentConfig = await kv.get("agent-config"); // Use AI to enhance the objective const enhancedObjective = await askAi( `Improve this task description: ${input.task}`, { temperature: 0.3 } ); // Start the agent const { executionId } = await agent.start({ objective: enhancedObjective }, agentConfig.functions); // Log the execution await fn.executeFunction("myusername/log-agent-start", { executionId, originalTask: input.task, enhancedObjective }); // Store execution reference await kv.set(`execution:${executionId}`, { task: input.task, startTime: new Date(), config: agentConfig }); return { executionId, objective: enhancedObjective }; } ``` -------------------------------- ### Scheduled (Cron) Trigger Function (JavaScript) Source: https://docs.microfn.dev/triggers Example of a JavaScript function designed to be triggered by a cron schedule. The function receives an empty input object and is intended for automated, time-based tasks. ```javascript // Configured in workspace settings // Cron expression: "0 9 * * *" (daily at 9 AM) export default async function main() { // Function receives empty input {} await performDailyTasks(); return { success: true }; } ``` -------------------------------- ### Import AI Module Source: https://docs.microfn.dev/modules/ai Imports the `askAi` function from the `@microfn/ai` module. This is the primary function used to interact with the AI. ```javascript import { askAi } from "@microfn/ai"; ``` -------------------------------- ### Invoke HTTP Webhook Trigger (cURL) Source: https://docs.microfn.dev/triggers Example of how to invoke a Microfn function using an HTTP POST request. This is suitable for direct API calls and integrations. It sends a JSON payload to a specified function endpoint. ```curl curl -X POST https://microfn.dev/run/username/function-name \ -H "Content-Type: application/json" \ -d '{"input": "data"}' ``` -------------------------------- ### Load Type-Safe Configuration with Defaults Source: https://docs.microfn.dev/configuration Implements type-safe configuration loading using TypeScript interfaces with fallback defaults. Retrieves API keys, URLs, and timeout settings from secrets, providing default values for optional parameters. Ensures configuration consistency and type checking at compile time. ```typescript interface Config { apiKey: string; apiUrl: string; timeout: number; retries: number; } async function loadConfig(): Promise { return { apiKey: await secret.getRequired("API_KEY"), apiUrl: await secret.get("API_URL", "https://api.example.com"), timeout: parseInt(await secret.get("TIMEOUT", "5000")), retries: parseInt(await secret.get("RETRIES", "3")) }; } export default async function main(input) { const config = await loadConfig(); // Use type-safe config const response = await fetchWithRetry( config.apiUrl, config.apiKey, config.retries ); return response; } ``` -------------------------------- ### Environment-Specific Configuration Logic Source: https://docs.microfn.dev/configuration Demonstrates how to implement environment-specific configuration within a function using secrets. It fetches an environment variable to determine whether to use development or production settings for API URLs and debug modes. This allows for different configurations based on the deployment environment. ```javascript import secret from "@microfn/secret"; export default async function main(input) { const env = await secret.get("ENVIRONMENT", "development"); const config = { development: { apiUrl: "https://dev.api.example.com", debug: true }, production: { apiUrl: "https://api.example.com", debug: false } }; return config[env] || config.development; } ``` -------------------------------- ### Import @microfn/kv Module Source: https://docs.microfn.dev/modules/kv Import the key-value storage module to enable persistent data storage in your functions. This module provides async methods for storing and retrieving data that persists across function executions. ```javascript import kv from "@microfn/kv"; ``` -------------------------------- ### Connect to Database using @microfn/secret Source: https://docs.microfn.dev/modules/secret This snippet demonstrates building a database connection string by retrieving multiple required secrets for host, user, and password, and an optional secret for the database name. It handles potential errors if required secrets are missing. ```javascript import secret from "@microfn/secret"; export default async function main() { try { const host = await secret.getRequired("DB_HOST"); const user = await secret.getRequired("DB_USER"); const password = await secret.getRequired("DB_PASSWORD"); const dbName = await secret.get("DB_NAME", "default_db"); const connectionString = `postgres://${user}:${password}@${host}/${dbName}`; // ... connect to database return { connected: true }; } catch (error) { return { error: "Database configuration is incomplete." }; } } ``` -------------------------------- ### Type-Safe KV Storage with TypeScript Source: https://docs.microfn.dev/modules Illustrates type safety when using the @microfn/kv module with TypeScript. It shows how to define an interface for user preferences and use it with `kv.set` and `kv.get` to ensure type-correct storage and retrieval of data. ```typescript import kv from "@microfn/kv"; interface UserPreferences { theme: "light" | "dark"; language: string; } // Type-safe storage and retrieval await kv.set("prefs", { theme: "dark", language: "en" }); const prefs = await kv.get("prefs"); ``` -------------------------------- ### Get Agent Execution Status Source: https://docs.microfn.dev/modules/agent Retrieve the current status of an asynchronous agent execution using the execution ID. Returns status information including current state (waiting, running, completed, failed), progress updates, and final results when available. ```javascript import agent from "@microfn/agent"; export default async function main(input: { executionId: string }) { const status = await agent.getStatus(input.executionId); switch (status.status) { case "completed": return { success: true, result: status.result, message: "Agent task completed successfully" }; case "failed": return { success: false, error: "Agent execution failed", details: status.progress }; case "running": return { success: true, status: "running", progress: status.progress, message: "Agent is still working..." }; case "waiting": return { success: true, status: "waiting", message: "Agent is waiting to start" }; default: return { error: "Unknown status" }; } } ``` -------------------------------- ### Debug Configuration and Environment Source: https://docs.microfn.dev/configuration Provides debugging utility to inspect configuration state including secret availability, environment variables, secret count, and node package paths. Returns boolean checks for critical secrets and metadata for troubleshooting configuration issues in deployed functions. ```javascript export default async function debugConfig() { return { hasApiKey: await secret.has("API_KEY"), environment: await secret.get("ENVIRONMENT", "not set"), secretCount: Object.keys(await secret.getWithPrefix("")).length, packages: process.env.NODE_PATH }; } ``` -------------------------------- ### Access Multi-Environment Secrets Source: https://docs.microfn.dev/configuration Explains how to handle secrets that vary across different environments (e.g., DEV, PROD, STAGING) by using environment variable prefixes. It retrieves the current environment and then constructs the specific secret key to access the correct API key. This pattern is useful for managing environment-specific credentials. ```javascript // Secrets configured: // DEV_API_KEY, PROD_API_KEY, STAGING_API_KEY const env = await secret.get("ENV", "DEV"); const apiKey = await secret.getRequired(`${env}_API_KEY`); ``` -------------------------------- ### Configure Local MCP Client for AI Assistants Source: https://docs.microfn.dev/integrations/mcp This configuration allows local development environments to connect to a remote MCP server, enabling AI assistants to discover and execute local Microfn functions. It requires an AI assistant that supports remote MCP servers and specifies the command to run the MCP client. ```json { "mcpServers": { "microfn": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.microfn.dev/sse"] } } } ``` -------------------------------- ### Create a Simple Greeting Function Source: https://docs.microfn.dev/integrations/mcp This TypeScript function creates a simple 'greet' function that takes a 'name' as input and returns a personalized greeting message. It demonstrates how an AI assistant can dynamically create new functions. ```typescript /** * Greets a user by name. * @param input.name The name to greet. * @returns A greeting message. */ export default async function main(input: { name: string }) { return `Hello, ${input.name}!`; } ``` -------------------------------- ### Define Configuration Schema in JSON Source: https://docs.microfn.dev/configuration Declares configuration schema in JSON format defining required secrets and their descriptions, along with package dependencies and versions. Provides a declarative way to document configuration requirements and manage dependencies centrally for infrastructure-as-code workflows. ```json { "secrets": { "API_KEY": { "description": "Primary API key", "required": true }, "DATABASE_URL": { "description": "Database connection string", "required": true } }, "packages": { "lodash": "^4.17.21", "axios": "^1.0.0", "date-fns": "^2.29.0" } } ``` -------------------------------- ### Store User Preferences with @microfn/kv Source: https://docs.microfn.dev/modules/kv Persists user-specific settings and preferences indexed by user ID. Saves preference objects to storage and immediately retrieves them to confirm successful storage. ```javascript export async function main({ userId, prefs }) { const key = `user:${userId}:prefs`; await kv.set(key, prefs); const savedPrefs = await kv.get(key); return { success: true, saved: savedPrefs }; } ``` -------------------------------- ### Export Configuration with Masked Secrets Source: https://docs.microfn.dev/configuration Exports workspace configuration including all secrets with masked sensitive values for auditing and backup purposes. Retrieves all secrets with empty prefix, masks values to show only first 3 characters, and includes packages and export timestamp. Useful for secure configuration backups. ```javascript import secret from "@microfn/secret"; export default async function exportConfig() { const allSecrets = await secret.getWithPrefix(""); // Mask sensitive values const masked = {}; for (const [key, value] of Object.entries(allSecrets)) { masked[key] = value.substring(0, 3) + "***"; } return { secrets: Object.keys(masked), packages: await getWorkspacePackages(), exported: new Date() }; } ``` -------------------------------- ### Implement Simple Counter with @microfn/kv Source: https://docs.microfn.dev/modules/kv Tracks hit counts for specific routes or events by incrementing and persisting a numeric value. Initializes counter to 0 if not previously stored and returns the updated count. ```javascript export async function main({ route }) { const key = `hits:${route}`; const currentHits = (await kv.get(key).catch(() => 0)) + 1; await kv.set(key, currentHits); return { route, hits: currentHits }; } ``` -------------------------------- ### Validate Required Secrets on Startup Source: https://docs.microfn.dev/configuration Validates that all required secrets are present before function execution using the @microfn/secret module. Checks for API_KEY, DATABASE_URL, and AUTH_TOKEN, throwing an error if any are missing. Essential for preventing runtime failures due to misconfiguration. ```javascript import secret from "@microfn/secret"; async function validateConfiguration() { const required = [ "API_KEY", "DATABASE_URL", "AUTH_TOKEN" ]; const missing = []; for (const key of required) { if (!await secret.has(key)) { missing.push(key); } } if (missing.length > 0) { throw new Error(`Missing required secrets: ${missing.join(", ")}`); } } export default async function main(input) { await validateConfiguration(); // Function logic here return { success: true }; } ``` -------------------------------- ### Format Output for Zapier Integration Source: https://docs.microfn.dev/integrations A JavaScript function structured to return data in a format expected by Zapier. This enables seamless integration of Microfn functions into Zapier workflows, processing data and returning results. ```javascript export default async function main(input) { // Process Zapier payload const result = await processData(input); // Return in Zapier-expected format return { id: result.id, status: "success", data: result }; } ``` -------------------------------- ### Use NPM Packages in Functions Source: https://docs.microfn.dev/configuration Illustrates how to use an NPM package (lodash) within a Microfn serverless function. The package is imported and used to process input data. Packages are managed through the dashboard or API and deployed as Lambda layers. ```javascript // After adding 'lodash' package to workspace import _ from "lodash"; export default async function main(input) { const sorted = _.orderBy(input.data, ['date'], ['desc']); return { sorted }; } ``` -------------------------------- ### Call External API with Authentication Source: https://docs.microfn.dev/integrations Demonstrates how to make a secure API call from a Microfn function to an external service. It retrieves an API key from secrets and includes it in the request headers for authentication. ```javascript import secret from "@microfn/secret"; export default async function main(input) { const apiKey = await secret.getRequired("EXTERNAL_API_KEY"); const response = await fetch("https://api.service.com/endpoint", { headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }, body: JSON.stringify(input) }); return await response.json(); } ``` -------------------------------- ### Content Generation Agent - TypeScript Source: https://docs.microfn.dev/modules/agent Activates a content generation agent to create content for a specified topic, platform, and tone. The agent uses functions for research, content generation, optimization, hashtag creation, and image generation. ```typescript import agent from "@microfn/agent"; export default async function main(input: { topic: string; platform: "twitter" | "linkedin" | "blog"; tone: string; }) { const { executionId } = await agent.start({ objective: `Create ${input.platform} content about ${input.topic} with a ${input.tone} tone. Research the topic, generate content, and optimize for the platform.` }, [ { function: "myusername/research-topic", description: "Researches information about a topic" }, { function: "myusername/generate-content", description: "Generates written content" }, { function: "myusername/optimize-for-platform", description: "Optimizes content for specific social media platform" }, { function: "myusername/generate-hashtags", description: "Generates relevant hashtags" }, { function: "myusername/create-image", description: "Creates accompanying images" } ]); return { executionId }; } ``` -------------------------------- ### Handle PayPal Webhooks Source: https://docs.microfn.dev/integrations This JavaScript function processes PayPal webhooks, including verification of the webhook signature. It requires a `verifyPayPalWebhook` function to be defined elsewhere. It handles the 'PAYMENT.CAPTURE.COMPLETED' event and returns an error for invalid signatures. ```javascript export default async function main(input) { const { event_type, resource } = input; // Verify PayPal webhook const verified = await verifyPayPalWebhook(input); if (!verified) { return { error: "Invalid webhook signature" }; } // Process PayPal event switch(event_type) { case "PAYMENT.CAPTURE.COMPLETED": return handlePaymentComplete(resource); default: return { processed: true }; } } ``` -------------------------------- ### Import @microfn/fn Module Source: https://docs.microfn.dev/modules/fn Import the @microfn/fn module to access function invocation capabilities within your workspace. This is the foundational import required before using any function execution features. ```javascript import fn from "@microfn/fn"; ``` -------------------------------- ### Import @microfn/secret Module Source: https://docs.microfn.dev/modules/secret This snippet shows how to import the @microfn/secret module into your project. No external dependencies are required beyond the module itself. ```javascript import secret from "@microfn/secret"; ``` -------------------------------- ### Handle Slack Slash Command Source: https://docs.microfn.dev/integrations Processes Slack slash commands received by a Microfn function. It checks for a '/microfn' command and generates a response suitable for Slack, including text and optional attachments. ```javascript export default async function main(input) { const { command, text, user_name, channel_id } = input; if (command === "/microfn") { const result = await processSlackCommand(text, user_name); return { response_type: "in_channel", text: result.message, attachments: result.attachments }; } } ```