# How Skill Files Are Managed in TencentDB Agent Memory: encodeUtf8, encodeBase64, writeFiles, and readFile Explained

> Learn how TencentDB Agent Memory manages skill files using encodeUtf8, encodeBase64, writeFiles, and readFile. Discover how payloads are prepared, uploaded, and retrieved for efficient resource management.

- Repository: [Tencent Cloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
- Tags: how-to-guide
- Published: 2026-08-31

---

**Skill files in the TencentDB Agent Memory SDK are managed through encoding helpers (`encodeUtf8` and `encodeBase64`) that prepare payloads for upload, with `writeFiles` sending batches to the server and `readFile` retrieving resources for client-side decoding.**

The **TencentDB-Agent-Memory** TypeScript SDK provides a `SkillClient` class that encapsulates all skill resource operations. Skills are modular units storing executable code, configuration, and documentation—this article examines how the SDK handles file encoding, writing, and reading operations based on the actual source implementation.

## encodeUtf8 and encodeBase64: Preparing File Payloads

Before uploading files to a skill, you must encode them into the `SkillResourcePayload` format the server expects. The SDK provides two encoding helpers in [`skill-client.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/skill-client.ts) for different content types.

### encodeUtf8 for Text Content

Use `SkillClient.encodeUtf8` for text-based files—JSON, markdown, YAML, or source code:

```typescript
SkillClient.encodeUtf8(
  path: string,
  content: string,
  opts?: { mime_type?: string; is_executable?: boolean }
): SkillResourcePayload

```

The payload includes:
- `path`: Target file path within the skill
- `content`: Raw UTF-8 string
- `encoding`: Fixed value `"utf-8"`
- Optional `mime_type` and `is_executable` flags

### encodeBase64 for Binary Content

Use `SkillClient.encodeBase64` for binary files—images, compiled binaries, or compressed archives:

```typescript
SkillClient.encodeBase64(
  path: string,
  bytes: Buffer | Uint8Array | ArrayBuffer | string,
  opts?: { mime_type?: string; is_executable?: boolean }
): SkillResourcePayload

```

The implementation at [`skill-client.ts#L67-L89`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/sdk/memory-core/typescript/src/v3/skill-client.ts#L67-L89) handles multiple input types:

| Input Type | Processing |
|------------|-----------|
| `string` | Assumed already Base64-encoded, used directly |
| `ArrayBuffer` | Converted to `Uint8Array` → `Buffer` → Base64 string |
| `Uint8Array` | Wrapped in `Buffer`, then `toString('base64')` |
| `Buffer` | Node.js Buffer treated as `Uint8Array` via compatibility |

This flexibility allows direct use of `fs.promises.readFile()` output or browser `fetch` array buffers.

## writeFiles: Uploading Encoded Resources

The `SkillClient.writeFiles` method sends batched payloads to the `/v3/skill/files/write` endpoint. The server stores files, increments the skill version, and returns an updated `SkillSummary`.

### Batch Upload Example

```typescript
import { SkillClient } from '@tencentcloud/memory-core';

const skillClient = new SkillClient({ region: 'ap-guangzhou' });

// Prepare mixed content types
const readmePayload = SkillClient.encodeUtf8(
  "docs/README.md",
  "# Database Optimizer Agent\nAutomated index recommendations for MySQL."

);

const schemaPayload = SkillClient.encodeUtf8(
  "config/schema.json",
  JSON.stringify({ tables: ["users", "orders"], version: "2.1" }),
  { mime_type: "application/json" }
);

const iconPayload = SkillClient.encodeBase64(
  "assets/icon.png",
  await fs.promises.readFile("./local/icon.png"),
  { mime_type: "image/png" }
);

const binaryPayload = SkillClient.encodeBase64(
  "bin/analyzer",
  await fs.promises.readFile("./analyzer-arm64"),
  { mime_type: "application/octet-stream", is_executable: true }
);

// Upload atomically
const result = await skillClient.writeFiles({
  skill_id: "skill-8f3a2e1d",
  expected_version: 4,
  files: [readmePayload, schemaPayload, iconPayload, binaryPayload],
});

console.log(`Skill updated to version ${result.version}`);

```

### Request Structure

The `writeFiles` call constructs this HTTP request body:

```typescript
{
  skill_id: string;           // Target skill identifier
  expected_version: number;   // Optimistic locking—must match current version
  files: SkillResourcePayload[]  // Array of encoded file objects
}

```

The `expected_version` parameter prevents concurrent modification conflicts. If the skill has changed since your last read, the server returns a version mismatch error.

## readFile: Retrieving and Decoding Skill Resources

While the SDK currently exposes `writeFiles` as the primary helper, the symmetric read operation follows the same payload principles. The server provides `/v3/skill/files/read` (documented in [[`v3-api-memorycore-doc.md`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/v3-api-memorycore-doc.md)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/MemoryCore/v3-api-memorycore-doc.md)), returning `SkillResourcePayload` objects that clients decode based on the `encoding` field.

### Manual Read and Decode Implementation

```typescript
async function readSkillFiles(
  skillClient: SkillClient,
  skillId: string,
  version: number,
  paths: string[]
): Promise<Map<string, Buffer | string>> {
  
  const response = await skillClient.http.post(
    `${SkillClient.V3}/files/read`,
    {
      skill_id: skillId,
      version: version,
      paths: paths,
    }
  );

  const files = response.files as SkillResourcePayload[];
  const results = new Map<string, Buffer | string>();

  for (const file of files) {
    if (file.encoding === "utf-8") {
      // Text content used directly
      results.set(file.path, file.content);
      
    } else if (file.encoding === "base64") {
      // Binary content reconstructed
      const buffer = Buffer.from(file.content, "base64");
      results.set(file.path, buffer);
    }
  }

  return results;
}

// Usage
const files = await readSkillFiles(
  skillClient,
  "skill-8f3a2e1d",
  5,
  ["docs/README.md", "assets/icon.png"]
);

await fs.promises.writeFile(
  "./download/icon.png",
  files.get("assets/icon.png") as Buffer
);

```

### Decoding Rules

- **`utf-8`**: The `content` field contains the raw string—no transformation needed
- **`base64`**: Decode via `Buffer.from(content, "base64")` in Node.js, or `atob()`/`Uint8Array` conversion in browsers

## Key Source Files and Architecture

| File | Role |
|------|------|
| [[`skill-client.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/skill-client.ts)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/sdk/memory-core/typescript/src/v3/skill-client.ts) | Implements `SkillClient` class with encoding helpers and write operations |
| [[`types.ts`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/types.ts)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/sdk/memory-core/typescript/src/v3/types.ts) | `SkillResourcePayload` interface definition |
| [[`v3-api-memorycore-doc.md`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/v3-api-memorycore-doc.md)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/MemoryCore/v3-api-memorycore-doc.md) | OpenAPI endpoint documentation for file operations |
| [[`MemoryKnowledge/openapi.yaml`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryKnowledge/openapi.yaml)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/MemoryKnowledge/openapi.yaml) | Complete OpenAPI specification |

The architecture separates **encoding concerns** (client-side in `SkillClient`) from **storage concerns** (server-side at `/v3/skill/files/*`). This design lets the SDK handle multiple input formats while maintaining a consistent wire protocol.

## Best Practices for Skill File Management

1. **Always specify `mime_type`** for non-text files—servers may use this for content-type headers when serving resources
2. **Use `expected_version`** for safe concurrent updates—retry on version conflicts with exponential backoff
3. **Batch related files** in single `writeFiles` calls—ensures atomic updates and reduces API round trips
4. **Stream large binaries** through `encodeBase64` with `Buffer` chunks rather than loading entire files into memory
5. **Validate paths** before encoding—server rejects paths containing `..` or absolute references

## Summary

- **`encodeUtf8`** creates UTF-8 payloads for text files with optional MIME type and executable flags
- **`encodeBase64`** normalizes `Buffer | Uint8Array | ArrayBuffer | string` inputs into Base64-encoded payloads for binary content
- **`writeFiles`** uploads batched payloads atomically to `/v3/skill/files/write` with optimistic version locking
- **`readFile`** (endpoint `/v3/skill/files/read`) returns payloads that clients decode based on the `encoding` field—`utf-8` for strings, `base64` for binary reconstruction

These primitives enable complete lifecycle management of skill resources in the TencentDB Agent Memory platform.

## Frequently Asked Questions

### What happens if I pass a Base64 string to encodeBase64?

The `encodeBase64` implementation detects string input and assumes it is already Base64-encoded, passing it through unchanged. This allows pre-encoded content but requires caution—passing raw UTF-8 strings will corrupt the payload. Always pass `Buffer` or `Uint8Array` for binary data you want automatically encoded.

### How does expected_version prevent conflicts?

The `expected_version` parameter implements optimistic concurrency control. The server compares your provided version against the current skill version; if they differ, the write fails with a version conflict error. Retry by re-reading the skill, merging your changes, and writing with the updated version.

### Can I read files without knowing their encoding in advance?

No—clients must inspect the `encoding` field in each returned `SkillResourcePayload`. The server does not alter content during storage, so the encoding you used during write is preserved. Always branch on `encoding === "utf-8"` versus `encoding === "base64"` before processing `content`.

### Is there a file size limit for writeFiles?

The source analysis does not specify limits, but the batch-oriented design suggests practical constraints. For large files, consult the [[`MemoryKnowledge/openapi.yaml`](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/main/MemoryKnowledge/openapi.yaml)](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/MemoryKnowledge/openapi.yaml) specification or implement chunked uploads if the server supports multipart transfers.