GuidesAI SDK

UI Tool Types

TypeScript types for Bluebag tools when used in your Typescript or React app

When building chat UIs with the AI SDK, you often need to type your messages with the tools available in your application.

The @bluebag/ai-sdk package exports TypeScript types for all Bluebag tools, designed to work smoothly with the AI SDK's UIMessage type.

Quick Start

import type { UIMessage } from "ai";
import type { BluebagToolTypes } from "@bluebag/ai-sdk";

// Define your custom tools
type MyCustomTools = {
  getWeather: {
    input: { location: string };
    output: { temperature: number; conditions: string };
  };
};

// Combine with Bluebag tools
type ChatTools = MyCustomTools & BluebagToolTypes;

// Use in your message type
type ChatMessage = UIMessage<unknown, UIDataTypes, ChatTools>;

// if you have custom metadata and datatypes:
type Metadata = {}; // your custom metadata
type CustomUIDataTypes = {}; // your custom UI data types 
type ChatMessage = UIMessage<Metadata, CustomUIDataTypes, ChatTools>;

Available Types

Aggregate Type

The easiest way to add all Bluebag tool types is with BluebagToolTypes:

import type { BluebagToolTypes } from "@bluebag/ai-sdk";

// BluebagToolTypes includes:
// - bluebag_bash
// - bluebag_code_execution
// - bluebag_computer_use
// - bluebag_text_editor
// - bluebag_file_download_url

Individual Tool Types

For more granular control, import individual tool types:

import type {
  BluebagBashTool,
  BluebagCodeExecutionTool,
  BluebagComputerUseTool,
  BluebagTextEditorTool,
  BluebagFileDownloadUrlTool,
} from "@bluebag/ai-sdk";

type ChatTools = {
  bluebag_bash: BluebagBashTool;
  bluebag_code_execution: BluebagCodeExecutionTool;
  bluebag_computer_use: BluebagComputerUseTool;
  // ... add only the tools you need
};

Input & Output Types

Access input and output types separately for custom use cases:

import type {
  // Input types
  BluebagBashInput,
  BluebagCodeExecutionInput,
  BluebagComputerUseInput,
  BluebagTextEditorInput,
  BluebagFileDownloadUrlInput,
  // Output types
  BluebagExecutionOutput,
  BluebagComputerUseOutput,
  BluebagTextEditorOutput,
  BluebagFileDownloadUrlOutput,
} from "@bluebag/ai-sdk";

Shared Types

Common types used across tools:

import type { BluebagArtifact, BluebagFileReference } from "@bluebag/ai-sdk";

// BluebagArtifact - metadata for files created during execution
type BluebagArtifact = {
  fileId: string;
  filename: string;
  path: string;
  size?: number;
  expiryAt?: string;
};

// BluebagFileReference - for mounting files into the sandbox
type BluebagFileReference = {
  fileId: string;
  path: string;
};

Type Reference

bluebag_bash

Execute shell commands in the sandbox.

type BluebagBashTool = {
  input: {
    command: string;
  };
  output: {
    exitCode: number;
    result: string;
    artifacts?: BluebagArtifact[];
  };
};

bluebag_code_execution

Execute Python, JavaScript, or TypeScript code.

type BluebagCodeExecutionTool = {
  input: {
    language: "python" | "javascript" | "typescript";
    code: string;
    files?: BluebagFileReference[];
  };
  output: {
    exitCode: number;
    result: string;
    artifacts?: BluebagArtifact[];
  };
};

bluebag_computer_use

Control the sandbox desktop environment.

type BluebagComputerUseTool = {
  input: {
    action: "screenshot" | "click" | "type" | "key";
    coordinate?: [number, number];
    text?: string;
  };
  output: {
    result: string;
    screenshot?: string;
  };
};

bluebag_text_editor

View and edit files in the sandbox.

type BluebagTextEditorTool = {
  input: {
    command: "view" | "create" | "str_replace";
    path: string;
    file_text?: string;
    old_str?: string;
    new_str?: string;
    start_line?: number;
    end_line?: number;
  };
  output: {
    result?: string;
    error?: string;
  };
};

bluebag_file_download_url

Generate short-lived download URLs for sandbox files.

type BluebagFileDownloadUrlTool = {
  input: {
    fileId: string;
    ttlSeconds?: number;
  };
  output: {
    fileId: string;
    downloadUrl: string;
    expiresAt: string;
  };
};

Full Example

Here's a complete example showing how to set up typed chat messages:

import type { UIMessage } from "ai";
import type { InferUITool } from "ai";
import { z } from "zod";
import type { BluebagToolTypes, BluebagArtifact } from "@bluebag/ai-sdk";

// Your custom tools
import type { getWeather } from "./tools/get-weather";
import type { createDocument } from "./tools/create-document";

// Message metadata schema
export const messageMetadataSchema = z.object({
  createdAt: z.string(),
});

export type MessageMetadata = z.infer<typeof messageMetadataSchema>;

// Custom UI data types
export type CustomUIDataTypes = {
  textDelta: string;
  suggestion: { id: string; text: string };
  clear: null;
  finish: null;
};

// Combine your tools with Bluebag tools
type weatherTool = InferUITool<typeof getWeather>;
type createDocumentTool = InferUITool<ReturnType<typeof createDocument>>;

export type ChatTools = {
  getWeather: weatherTool;
  createDocument: createDocumentTool;
} & BluebagToolTypes;

// Final typed message
export type ChatMessage = UIMessage<
  MessageMetadata,
  CustomUIDataTypes,
  ChatTools
>;

Handling Tool Invocations in UI

With typed messages, you get full type safety when rendering tool invocations:

import type { ChatMessage, ChatTools } from "./types";

function ToolResult({ part }: { part: ChatMessage["parts"][number] }) {
  if (part.type !== "tool-invocation") return null;

  const { toolInvocation } = part;

  switch (toolInvocation.toolName) {
    case "bluebag_bash":
      // TypeScript knows the input/output shapes
      return (
        <div>
          <code>{toolInvocation.input.command}</code>
          {toolInvocation.state === "result" && (
            <pre>{toolInvocation.output.result}</pre>
          )}
        </div>
      );

    case "bluebag_code_execution":
      return (
        <div>
          <span>Language: {toolInvocation.input.language}</span>
          <pre>{toolInvocation.input.code}</pre>
          {toolInvocation.state === "result" && (
            <>
              <pre>{toolInvocation.output.result}</pre>
              {toolInvocation.output.artifacts?.map((artifact) => (
                <FilePreview key={artifact.fileId} artifact={artifact} />
              ))}
            </>
          )}
        </div>
      );

    case "bluebag_file_download_url":
      if (toolInvocation.state === "result") {
        return <a href={toolInvocation.output.downloadUrl}>Download File</a>;
      }
      return <span>Generating download link...</span>;

    // ... handle other tools
  }
}

Tool Name Union Type

For exhaustive switch statements or tool filtering:

import type { BluebagToolName } from "@bluebag/ai-sdk";

// BluebagToolName =
//   | "bluebag_bash"
//   | "bluebag_code_execution"
//   | "bluebag_computer_use"
//   | "bluebag_text_editor"
//   | "bluebag_file_download_url"

function isBluebagTool(toolName: string): toolName is BluebagToolName {
  return toolName.startsWith("bluebag_");
}

On this page