# How Large Responses Are Handled and Summarized in Craft-Agents-OSS

> Craft-Agents-OSS automatically handles large responses by detecting binary data, extracting assets, persisting payloads, and summarizing to prevent context overflow.

- Repository: [Craft Docs/craft-agents-oss](https://github.com/lukilabs/craft-agents-oss)
- Tags: how-to-guide
- Published: 2026-04-18

---

**Craft-Agents-OSS automatically routes oversized tool outputs through a specialized pipeline that detects binary data, extracts embedded assets, persists payloads to disk, and optionally generates LLM summaries to prevent context window overflow.**

When building agentic systems with the [lukilabs/craft-agents-oss](https://github.com/lukilabs/craft-agents-oss) repository, tool calls often return massive payloads—API results, HTML pages, or base64-encoded media. The framework's **large-response** utility in [`packages/shared/src/utils/large-response.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/utils/large-response.ts) intercepts these results, ensuring the main agent context remains within token limits while preserving full data accessibility.

## The Large-Response Processing Pipeline

The system uses a multi-stage decision tree to classify and handle responses. The entry point is `guardLargeResult` (lines 58–70), which branches based on content type, size, and structure.

### Binary Detection and Safe Storage

Before any text processing occurs, the raw bytes are scanned for binary signatures via `looksLikeBinary`. If detected, the utility immediately saves the data to disk using `saveBinaryResponse` and returns a concise placeholder message to the agent.

This prevents binary garbage from polluting the LLM context while ensuring the asset remains available for downstream tools.

### Structured JSON Asset Extraction

When the response is JSON, the system walks the object tree to find embedded base64-encoded assets. The `extractAssetsFromStructuredJson` function (lines 200–267) decodes these blobs, writes them to separate files, and rewrites the JSON pointers to reference the saved paths.

The `formatStructuredMediaExtractionMessage` function (lines 281–296) then generates a summary message listing the extracted files, allowing the agent to understand what media was retrieved without receiving the full base64 strings.

### Inline Base64 and Data URL Handling

For plain-text responses containing data URLs or raw base64 blobs, the system detects these patterns at line 84 within `guardLargeResult`. The encoded data is decoded, persisted to the `long_responses/` directory, and replaced with a short confirmation message indicating the binary content was saved externally.

## Token-Based Thresholds and Persistence

The utility enforces strict size limits to protect the context window.

### Size Estimation and Limits

The `estimateTokens` function (lines 40–45) calculates the approximate token count of the response text. The system compares this against **TOKEN_LIMIT** (15,000 tokens, approximately 60 KB).

If the response is below this threshold, the original result is returned unchanged, minimizing overhead for typical payloads.

### Saving Oversized Responses

When the payload exceeds **TOKEN_LIMIT**, the `saveLargeResponse` function (lines 68–88) writes the full content to the session’s `long_responses/` folder. This directory is defined in [`packages/shared/src/sessions/storage.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/sessions/storage.ts).

The file path is preserved so that later tool calls—such as `Read`, `Grep`, or `transform_data`—can access the specific data without reloading the entire payload into the agent's context.

## Optional LLM Summarization

For payloads that are large but not enormous, the system can generate a condensed summary to give the agent immediate context.

### Summarization Triggers

If a summarization callback is provided (typically the agent’s `runMiniCompletion` method) and the payload is under **MAX_SUMMARIZATION_INPUT** (100,000 tokens, approximately 400 KB), the system proceeds to summarize.

The `buildSummarizationPrompt` function (lines 123–168) constructs a specialized prompt that includes the tool name, endpoint, parameters, and a truncated excerpt of the response, instructing the mini-model to extract key information.

### Summary Formatting

The `formatLargeResponseMessage` function (lines 90–107) assembles the final message presented to the main agent. If summarization succeeded, the message includes:

```

[Large response (~<tokens> tokens) summarized]

Full data saved to: /path/to/file.txt
- Use Read/Grep to access specific content
- Use transform_data with inputFiles: ["long_responses/..."] for data analysis

<summary>

```

If no summary is available, a preview of the first 2 KB is included instead.

## Implementation Examples

### Direct Usage of the Guard Function

To process a tool output before sending it to the model:

```typescript
import { guardLargeResult } from '@/utils/large-response.ts';

const result = await guardLargeResult(toolOutput, {
  sessionPath: '/tmp/session/123',
  toolName: 'gmail',
  input: { query: 'in:inbox' },
  intent: 'summarize',
  summarize: agent.runMiniCompletion.bind(agent),
});

if (result) {
  console.log(result);
}

```

*Relevant source*: `guardLargeResult` (lines 48–98) in [`packages/shared/src/utils/large-response.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/utils/large-response.ts).

### Registering a Summarization Callback

Agents register their summarization capability via:

```typescript
class ClaudeAgent {
  private summarizeCallback?: (prompt: string) => Promise<string | null>;

  setSummarizeCallback(fn: (prompt: string) => Promise<string | null>) {
    this.summarizeCallback = fn;
  }
}

// When building an API tool:
const apiTool = createApiTool(config, cred, sessionPath, this.summarizeCallback);

```

*Relevant source*: `setSummarizeCallback` method in `McpClientPool` (lines 124–140) in [`packages/shared/src/mcp/mcp-pool.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/mcp/mcp-pool.ts).

### Building a Summarization Prompt

```typescript
const prompt = buildSummarizationPrompt(veryLongText, {
  toolName: 'github',
  path: '/repos/lukilabs/craft-agents-oss',
  input: { repo: 'craft-agents-oss' },
  intent: 'Summarize recent PR changes',
});

```

*Source*: `buildSummarizationPrompt` (lines 123–168) in [`packages/shared/src/utils/large-response.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/utils/large-response.ts).

## Summary

- **Binary detection** occurs first via `looksLikeBinary` in `guardLargeResult`, saving non-text data immediately to prevent context pollution.
- **Asset extraction** from JSON and plain text removes base64 blobs, replaces them with file references, and generates inventory messages.
- **Token thresholds** (`TOKEN_LIMIT` ≈ 15k tokens) determine whether a response passes through unchanged or gets persisted to the `long_responses/` directory.
- **Optional summarization** uses `buildSummarizationPrompt` and `runMiniCompletion` for payloads under 100k tokens, producing condensed context for the agent.
- **Reference formatting** via `formatLargeResponseMessage` ensures the agent receives file paths, access instructions, and either a summary or preview snippet.

## Frequently Asked Questions

### What happens if a tool returns a binary file like a PDF or image?

The `guardLargeResult` function detects binary signatures using `looksLikeBinary` (lines 58–70) and immediately saves the data via `saveBinaryResponse`. The agent receives a short message like "Binary saved to: /path/to/file.pdf" instead of the raw bytes, keeping the context window clean.

### How does the system decide whether to summarize a response?

The utility checks two conditions: the response must exceed the `TOKEN_LIMIT` (15,000 tokens), and it must be smaller than `MAX_SUMMARIZATION_INPUT` (100,000 tokens). If both conditions are met and a summarization callback was provided (typically `runMiniCompletion`), the system calls `buildSummarizationPrompt` and generates a summary.

### Where are large responses stored on disk?

All oversized responses are written to the `long_responses/` subdirectory within the session folder, as defined in [`packages/shared/src/sessions/storage.ts`](https://github.com/lukilabs/craft-agents-oss/blob/main/packages/shared/src/sessions/storage.ts). The `saveLargeResponse` function (lines 68–88) handles the file I/O, and the resulting path is passed back to the agent for later access via `Read`, `Grep`, or `transform_data` tools.

### Can the agent access the full response after it has been summarized?

Yes. When a response is summarized, the `formatLargeResponseMessage` function (lines 90–107) includes the full file path in the return message. The agent can then use tools like `Read` or `Grep` to access specific portions of the saved file, or use `transform_data` with `inputFiles: ["long_responses/..."]` to perform data analysis on the complete payload.