Typescript sdk

Context Fetchers

Copy page

Learn how to use context fetchers to fetch data from external sources and make it available to your agents

Overview

Context fetchers allow you to embed real-time data from external APIs into your agent prompts. Instead of hardcoding information in your agent prompt, context fetchers dynamically retrieve fresh data for each conversation.

Key Features

  • Dynamic data retrieval: Fetch real-time data from APIs.
  • Dynamic Prompting: Use dynamic data in your agent prompts
  • Request context integration: Use request-specific parameters to customize data fetching.
  • Data transformation: Transform API responses into the exact format your agent needs.

Context Fetchers vs Tools

  • Context Fetchers: Pre-populate agent prompts with dynamic data

    • Run automatically before/during conversation startup
    • Data becomes part of the agent's system prompt
    • Perfect for: Personalized agent personas, dynamic agent guardrails
    • Example Prompt: You are an assistant for ${userContext.toTemplate('user.name')} and you work for ${userContext.toTemplate('user.organization')}
  • Tools: Enable agents to take actions or fetch data during conversations

    • Called by the agent when needed during the conversation
    • Agent decides when and how to use them
    • Example Tool Usage: Agent calls a "send_email" tool or "search_database" tool

Basic Usage

Let's create a simple context fetcher that retrieves user information:

import { z } from "zod";
import { agent, agentGraph } from "@inkeep/agents-manage-api/builders";
import { contextConfig, fetchDefinition, requestContextSchema } from "@inkeep/agents-core";

// 1. Define request schema for headers validation. All header keys are converted to lowercase.
// In this example all incoming headers will be validated to make sure they include user_id and api_key.
const requestContext = requestContextSchema({
  schema: z.object({
    user_id: z.string(),
    api_key: z.string(),
  })
});

// 2. Create the fetcher with
const userFetcher = fetchDefinition({
  id: "user-info",
  name: "User Information",
  trigger: "initialization", // Fetch only once when a conversation is started with the graph. When set to "invocation", the fetch will be executed every time a request is made to the graph.
  fetchConfig: {
    url: `https://api.example.com/users/${requestContext.toTemplate('user_id')}`,
    method: "GET",
    headers: {
      Authorization: `Bearer ${requestContext.toTemplate('api_key')}`,
    },
    transform: "name", // Extract user's name from response, for example if the response is { "name": "John Doe", "email": "john.doe@example.com" }, the transform will return "John Doe"
  },
  responseSchema: z.string(), // Used to validate the result of the transformed api response.
  defaultValue: "Unable to fetch user information",
});

// 3. Configure context
const userContext = contextConfig({
  tenantId: "your-tenant",
  id: "user-context",
  name: "User Context",
  description: "Fetches user information for personalization",
  requestContextSchema: requestContext,
  contextVariables: {
    userName: userFetcher,
  },
});

// 4. Create and use the agent
const personalAgent = agent({
  id: "personal-agent",
  name: "Personal Assistant",
  description: "A personalized AI assistant",
  prompt: `Hello ${userContext.toTemplate('userName')}! I'm your personal assistant.`,
});

// Initialize the graph
export const graph = agentGraph({
  id: "personal-graph",
  name: "Personal Assistant Graph",
  defaultAgent: personalAgent,
  agents: () => [personalAgent],
  contextConfig: userContext,
});

Using Context Variables

Context variables can be used in your agent prompts using JSONPath template syntax {{contextVariableKey.field_name}}. Use the context config's toTemplate() method for type-safe templating with autocomplete and validation.

const userContext = contextConfig({
  tenantId: "your-tenant",
  id: "user-context",
  name: "User Context",
  description: "Fetches user information for personalization",
  requestContextSchema: requestContext,
  contextVariables: {
    user: userFetcher,
  },
});

const personalAgent = agent({
  id: "personal-agent",
  name: "Personal Assistant",
  description: "A personalized AI assistant",
  prompt: `Hello ${userContext.toTemplate('user.name')}! I'm your personal assistant. I can see that you work for ${userContext.toTemplate('requestContext.org_alias')}.`,
});

Context variables are resolved using JSONPath notation.

Data transformation

The transform property on fetch definitions lets you extract exactly what you need from API responses using JSONPath notation:

// API returns: { "user": { "profile": { "displayName": "John Doe" } } }
transform: "user.profile.displayName"; // Result: "John Doe"

// API returns: { "items": [{ "name": "First Item" }, { "name": "Second Item" }] }
transform: "items[0].name"; // Result: "First Item"

Best Practices

  1. Use Appropriate Triggers

    • initialization: Use when data rarely changes
    • invocation: Use for frequently changing data
  2. Handle Errors Gracefully

    • Always provide a defaultValue
    • Use appropriate response schemas
  • Request Context - Learn how to pass dynamic context to your agents via HTTP headers