Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agentium.in/llms.txt

Use this file to discover all available pages before exploring further.

Context Providers

Why

A common agent shape: “answer using these N markdown docs / this DB row / today’s status feed”. You can do that with tools (the LLM calls fetch_status() whenever it needs the data), but for context that the LLM always needs, tools are wasteful:
  • An extra round-trip per turn.
  • The LLM might forget to call.
  • Tool definitions take prompt space.
The alternative: pre-fetch the context and inject it into the system prompt before the model sees the user’s message. That’s what a ContextProvider does.

ContextProvider interface

interface ContextProvider {
  /** Stable name used in <context name="..."> wrapping. */
  readonly name: string;
  /**
   * Return the context string to inject, or null if no context is available for this query.
   * The query is the user's latest input; ctx is the standard RunContext (userId, sessionState, etc.).
   */
  fetch(query: string, ctx: RunContext): Promise<string | null>;
}
The framework wraps your return value as:
<context name="status-feed">
... your text here ...
</context>
Tags help the model distinguish multiple sources.

Built-in providers

FilesystemContextProvider

import { FilesystemContextProvider } from "@agentium/core";

const notes = new FilesystemContextProvider({
  basePath: "./agent-notes",
  glob: "*.md",                // default "**/*.md"
  encoding: "utf8",            // default "utf8"
  maxFileSize: 100 * 1024,     // default 100KB per file
  maxFiles: 20,                // default 20 files combined
});
Reads every file matching glob under basePath, concatenates them, returns the result. Files over maxFileSize are skipped. Total file count capped at maxFiles. Each file is prefixed with # <relative path> so the model knows what came from where. Use for: project README, design docs, prompt templates loaded from disk, user-uploaded notes.

HttpContextProvider

import { HttpContextProvider } from "@agentium/core";

const status = new HttpContextProvider({
  url: "https://status.example.com/api/current",
  method: "GET",                                       // default "GET"
  headers: { Authorization: `Bearer ${process.env.STATUS_TOKEN}` },
  body: undefined,                                     // optional, for POST
  timeoutMs: 5_000,                                    // default 5s
  cacheTtlMs: 60_000,                                  // default 0 (no cache)
});
Fetches the URL on every fetch() call unless cacheTtlMs > 0, in which case the result is cached for that many milliseconds. If the request fails (network error, non-2xx), the provider returns null and silently continues. No retries (wrap with your own if you need them). Use for: status feeds, configuration endpoints, “latest pricing” data.

DatabaseContextProvider

import { DatabaseContextProvider } from "@agentium/core";

const profile = new DatabaseContextProvider({
  name: "user-profile",
  fetch: async (ctx) => {
    const row = await db.users.findOne({ id: ctx.userId });
    if (!row) return null;
    return `name: ${row.name}\nplan: ${row.plan}\nsignup: ${row.signupAt}`;
  },
});
Thin wrapper that just adapts an arbitrary async function to the ContextProvider interface, with the name used for the <context> tag. Use for: anything that’s not a file or HTTP endpoint — DBs, cache, in-process Maps, custom APIs.

Plugging into an Agent

import { Agent, openai, resolveContextProviders } from "@agentium/core";

const providers = [notes, status, profile];

const agent = new Agent({
  name: "support-bot",
  model: openai("gpt-4o"),
  instructions: ({ context }) => `
You are a support assistant. Use the context below.

${context}

Be concise.`,
});

app.post("/chat", async (req, res) => {
  const ctx = { userId: req.user.id }; // any RunContext-shaped object
  const context = await resolveContextProviders(providers, req.body.input, ctx);
  const result = await agent.run(req.body.input, {
    context,            // merged context string
    userId: req.user.id,
  });
  res.json(result);
});
(Direct integration into the Agent’s instructions resolver is on the roadmap; for now, fetch the context and inject it yourself.)

resolveContextProviders(providers, query, ctx)

The helper that runs all providers in parallel and concatenates their outputs.
async function resolveContextProviders(
  providers: ContextProvider[],
  query: string,
  ctx: RunContext,
): Promise<string>;
  • Runs fetch() on every provider in parallel via Promise.allSettled.
  • Skips providers that throw or return null.
  • Wraps each non-null result in <context name="...">...</context>.
  • Returns the joined string (or "" if nothing returned).
If you need different orchestration (sequential, with-deadline, cancellable), drive the providers yourself.

Caching strategies

HttpContextProvider has built-in TTL caching. For the others, layer it yourself:
class CachedContextProvider implements ContextProvider {
  private cache?: { value: string | null; expires: number };

  constructor(
    private inner: ContextProvider,
    private ttlMs: number,
  ) {}

  get name() { return this.inner.name; }

  async fetch(query: string, ctx: RunContext) {
    const now = Date.now();
    if (this.cache && now < this.cache.expires) return this.cache.value;
    const value = await this.inner.fetch(query, ctx);
    this.cache = { value, expires: now + this.ttlMs };
    return value;
  }
}
Or just memoize at the orchestrator level.

Per-user context

ctx carries userId, tenantId, sessionState. Use them inside fetch() to personalize:
new DatabaseContextProvider({
  name: "preferences",
  fetch: async (ctx) => {
    const prefs = await db.preferences.findOne({ userId: ctx.userId });
    return prefs ? JSON.stringify(prefs) : null;
  },
});
The provider gets the same RunContext that the agent sees, so any state you’ve stashed via RunContext.sessionState is available.

Token cost considerations

Context is paid for on every turn. A 50KB markdown corpus injected into the system prompt costs ~$0.03 per turn at GPT-4o pricing.
  • Always-on, small: context provider is the right choice.
  • Sometimes-on, large: use a tool (searchNotes) or RAG retrieval instead.
  • Always-on, large: consider prompt caching (Anthropic’s cache_control, OpenAI’s prompt_caching) — Agentium honors both when the underlying provider supports them.

See also

  • Prompts and Instructions — how the resolved context gets composed into the system message
  • GraphRAG — when “context” is a graph query
  • Skills — the skill system is itself a kind of context provider (with extra structure)