The log function wrapper allows you to wrap functions with spans of different types. It serves two main purposes:

  1. It tells our logger to wrap the function contents as a span (you can specify the type in the first argument - by default a workflow span is created).
  2. If there is no current trace when you execute a function wrapped in log, it will create a single span trace.

Usage

import { log, init } from "galileo";

// Initialize Galileo
init({
  projectName: "my-project",
  logStreamName: "development",
});

const wrappedFunc = log({ name: "workflow span" }, (input:any) => {
  // Your code here
  return result;
});

const result = wrappedFunc("input data");

Span Types

The log function wrapper supports different span types:

  • workflow: A span that can have child spans, useful for nesting several child spans to denote a thread within a trace. If you wrap a parent function with log, calls that are made within that scope are automatically logged in the same trace.
  • llm: Captures the input, output, and settings of an LLM call. This span gets automatically created when our client library wrappers (OpenAI and Anthropic) are used. Cannot have nested children.
  • retriever: Contains the output documents of a retrieval operation.
  • tool: Captures the input and output of a tool call. Used to decorate functions that are invoked as tools.

Examples

Workflow Span with Nested LLM Calls

Create a trace with a workflow span and nested LLM spans:

import { OpenAI } from "openai";
import { wrapOpenAI, flush, log, init } from "galileo";

async function runExample() {
  const openai = wrapOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));

  // This will automatically create an llm span since we're using the `wrapOpenAI` wrapper
  const callOpenAI = async (input: any) => {
    const result = await openai.chat.completions.create({
      model: "gpt-4o",
      messages: [{ content: `Say hello ${input}!`, role: "user" }],
    });
    return result;
  };

  // Optionally initialize the logger if you haven't set GALILEO_PROJECT and GALILEO_LOG_STREAM environment variables
  await init({
    projectName: "my-project",
    logStreamName: "my-log-stream",
  });

  const wrappedToolCall = log({ name: "tool span", spanType: "tool" }, (input: any) => {
    return "tool call result";
  });

  const wrappedFunc = await log({ name: "workflow span" }, async (input: any) => {
    const result = await callOpenAI(input);
    return wrappedToolCall(result);
  });

  // This will create a workflow span with an llm span and a tool span
  const result = await wrappedFunc("world");

  await flush();

  return result;
}

// Run the example
runExample();

Retriever Span

Log a retriever function. If the output of the function is an array, it will automatically capture it as documents in the span:

import { log, init, flush } from "galileo";

async function runRetrieverExample() {
  // Initialize Galileo
  init({
    projectName: "my-project",
    logStreamName: "development",
  });

  const retriever = log({ name: "document retriever", spanType: "retriever" }, (query) => {
    // Retrieval logic
    return ["Document 1", "Document 2"];
  });

  const documents = retriever("search query");

  await flush();

  return documents;
}

// Run the example
runRetrieverExample();

API Reference

log

export type SpanType = 'workflow' | 'llm' | 'retriever' | 'tool';
export interface LogOptions {
  name?: string;
  spanType?: SpanType;
  params?: Record<string, unknown>;
}

// Wraps a function to log its execution as a span in Galileo.
export declare function log<T extends unknown[], R>(
  options: LogOptions
): (fn: (...args: T) => R) => (...args: T) => R;