@brian/claude-chat-client (0.1.2)

Published 2026-07-21 03:15:25 +00:00 by brian in brian/claudechatwindow

Installation

@brian:registry=
npm install @brian/claude-chat-client@0.1.2
"@brian/claude-chat-client": "0.1.2"

About this package

@brian/claude-chat-client

Shared Node/TypeScript Anthropic client for homeclaude and kittycharactersheet's backends (both already use @anthropic-ai/sdk directly). Owns the streaming request + tool-use round-trip loop; each app still supplies its own API key, model, and tool implementations, so per-app usage tracking is unchanged.

Usage

import { createClaudeClient } from "@brian/claude-chat-client";

const claude = createClaudeClient({
  apiKey: config.anthropicApiKey, // this app's own key, unchanged
  model: config.claudeModel,      // this app's own model, unchanged
});

const result = await claude.chat(
  {
    system: "You are ...",
    messages: conversationSoFar,
    tools: MY_APP_TOOLS,
  },
  {
    onTextDelta: (delta) => res.write(delta), // pipe into your existing SSE/NDJSON response
    onToolUse: (call) => logger.info("tool call", call),
    executeTool: async (call) => {
      switch (call.name) {
        case "create_calendar_event":
          return await createCalendarEvent(call.input);
        default:
          throw new Error(`unknown tool ${call.name}`);
      }
    },
  }
);

// result.messages -> persist as the new conversation history
// result.finalText -> full assistant text across all tool-loop rounds

Tool execution stays app-specific on purpose (calendar writes, dose logs, character-sheet edits, ...) — this package only owns the loop that calls the model, detects tool_use blocks, awaits your executeTool, and feeds tool_result blocks back in until the model stops asking for tools or maxToolRounds is hit (default 8).

Image attachments

imageContentBlock() builds a Claude image content block from base64 + media type (mirrors homeclaude's own buildAttachmentBlock()), for including in a user message's content array alongside a text block:

import { imageContentBlock, isSupportedImageType } from "@brian/claude-chat-client";

const content: Anthropic.MessageParam["content"] = [
  { type: "text", text: userText },
  ...images.map((img) => imageContentBlock({ mediaType: img.mediaType, base64: img.base64 })),
];

Only image/jpeg, image/png, image/gif, and image/webp are supported (SUPPORTED_IMAGE_MEDIA_TYPES) — check with isSupportedImageType() before calling imageContentBlock() on user-supplied media types.

pdfContentBlock({ base64, title }) and textContentBlock({ text, title }) cover homeclaude's other two attachment kinds (PDF, and its fallback for everything else — CSV, markdown, JSON, ... read as UTF-8 text):

import { pdfContentBlock, textContentBlock } from "@brian/claude-chat-client";

pdfContentBlock({ base64: pdfBytes.toString("base64"), title: "invoice.pdf" });
textContentBlock({ text: fileBytes.toString("utf8"), title: "notes.md" });

Dependencies

Dependencies

ID Version
@anthropic-ai/sdk ^0.100.1

Development dependencies

ID Version
typescript ^5.5.0
Details
npm
2026-07-21 03:15:25 +00:00
1
4.5 KiB
Assets (1)
Versions (5) View all
0.1.4 2026-07-21
0.1.3 2026-07-21
0.1.2 2026-07-21
0.1.1 2026-07-20
0.1.0 2026-07-20