[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/uppet/closer-code/master/API_GUIDE.md [Back]  [Original]

# Closer Code - Anthropic SDK 

>  Closer Code  `@anthropic-ai/sdk`  AI API 

---

## 

1. [](#1-)
2. [](#2-)
3. [](#3-)
4. [API ](#4-api-)
5. [ (Extended Thinking)](#5--extended-thinking)
6. [](#6-)
7. [](#7-)
8. [](#8-)

---

## 1. 

### 1.1 

```bash
npm install @anthropic-ai/sdk
```

### 1.2 5

#### closer_code 

```javascript
//  fetch...
const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': apiKey,
    'anthropic-version': '2023-06-01'
  },
  body: JSON.stringify(requestBody)
});
// ...
```

####  SDK 

```typescript
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY
});

const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  messages: [{ role: 'user', content: 'Hello, Claude!' }]
});

console.log(message.content);
```

****
-   HTTP 
-  
-  
-   80%

---

## 2. 

### 2.1 

|  |  | SDK  |
|------|---------|---------|
| **** | ~40  | ~5  |
| **SSE ** |  |  |
| **** |  |  |
| **** |  |  |

####  closer_code

```javascript
// ai-client.js: streamFetch 
async function streamFetch(url, options, onChunk) {
  const response = await fetch(url, options);
  if (!response.ok) {
    const error = await response.text();
    throw new Error(`API error: ${response.status} - ${error}`);
  }

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split('\n');
    buffer = lines.pop() || '';

    for (const line of lines) {
      if (line.trim().startsWith('data: ')) {
        const data = line.trim().slice(6);
        if (data === '[DONE]') continue;
        try {
          const parsed = JSON.parse(data);
          onChunk(parsed);
        } catch (e) {
          // 
        }
      }
    }
  }
}
```

#### SDK 

```typescript
const stream = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  messages: [{ role: 'user', content: 'Hello!' }],
  stream: true
});

for await (const event of stream) {
  console.log(event.type);
}
```

**87.5%**

### 2.2 Tool Use

|  |  | SDK  |
|------|---------|---------|
| **** |  schema |  schema  |
| **** |  |  |
| **** |  |  |
| **** | ~100  | ~20  |

####  closer_code

```javascript
// 
async function executeTools(aiClient, messages, tools) {
  let currentMessages = [...messages];

  while (true) {
    const response = await aiClient.chat(currentMessages, { tools });

    const toolResults = [];
    for (const block of response.content) {
      if (block.type === 'tool_use') {
        const result = await executeTool(block.name, block.input);
        toolResults.push({
          role: 'tool',
          toolUseId: block.id,
          content: result
        });
      }
    }

    if (toolResults.length === 0) {
      return response;
    }

    currentMessages.push({
      role: 'assistant',
      content: response.content
    });
    currentMessages.push(...toolResults);
  }
}
```

#### SDK  toolRunner

```typescript
import { z } from 'zod';
import { betaZodTool } from '@anthropic-ai/sdk/helpers/beta/zod';

const weatherTool = betaZodTool({
  name: 'get_weather',
  description: '',
  inputSchema: z.object({
    location: z.string().describe('')
  }),
  run: async (input) => {
    // 
    return `${input.location}  20C`;
  }
});

const finalMessage = await client.beta.messages.toolRunner({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  messages: [{ role: 'user', content: '' }],
  tools: [weatherTool]
});
```

**80%**

### 2.3 

|  |  | SDK  |
|------|---------|---------|
| **** |  |  |
| **** |  |  |
| **** |  |  |

####  closer_code

```javascript
// ai-client.js: 
const formattedMessages = messages.map(m => {
  if (m.role === 'tool') {
    return {
      role: 'user',
      content: [{
        type: 'tool_result',
        tool_use_id: m.toolUseId,
        content: m.content
      }]
    };
  }
  return {
    role: m.role,
    content: m.content
  };
});
```

#### SDK 

```typescript
import Anthropic from '@anthropic-ai/sdk';

// IDE 
const message: Anthropic.MessageParam = {
  role: 'user',
  content: 'Hello'
};

// 
const toolResult: Anthropic.ToolResultBlockParam = {
  type: 'tool_result',
  tool_use_id: 'toolu_xxx',
  content: ''
};
```

---

## 3. 

### 3.1  AnthropicClient 

####  1 SDK

```bash
npm install @anthropic-ai/sdk
```

####  2

**src/ai-client.js**

```javascript
export class AnthropicClient {
  constructor(config) {
    this.apiKey = config.apiKey;
    this.baseURL = config.baseURL || 'https://api.anthropic.com';
    this.model = config.model || 'claude-sonnet-4-5-20250929';
    this.maxTokens = config.maxTokens || 8192;
  }

  async chat(messages, options = {}) {
    // ... 
  }
}
```

**src/ai-client-sdk.js**

```typescript
import Anthropic from '@anthropic-ai/sdk';

export class AnthropicClientSDK {
  private client: Anthropic;
  private model: string;
  private maxTokens: number;

  constructor(config: { apiKey: string; model?: string; maxTokens?: number }) {
    this.client = new Anthropic({
      apiKey: config.apiKey
    });
    this.model = config.model || 'claude-sonnet-4-5-20250929';
    this.maxTokens = config.maxTokens || 8192;
  }

  async chat(messages: Anthropic.MessageParam[], options?: {
    system?: string;
    tools?: Anthropic.Tool[];
    temperature?: number;
  }) {
    return await this.client.messages.create({
      model: this.model,
      max_tokens: this.maxTokens,
      system: options?.system,
      messages,
      tools: options?.tools,
      temperature: options?.temperature
    });
  }

  async chatStream(
    messages: Anthropic.MessageParam[],
    options?: { system?: string; tools?: Anthropic.Tool[] },
    onChunk: (event: Anthropic.RawMessageStreamEvent) => void
  ) {
    const stream = await this.client.messages.create({
      model: this.model,
      max_tokens: this.maxTokens,
      system: options?.system,
      messages,
      tools: options?.tools,
      stream: true
    });

    for await (const event of stream) {
      onChunk(event);
    }
  }
}
```

**70%**

### 3.2 

####  11-2

-  `AnthropicClient` 
-  `AnthropicClientSDK` 
-  SDK

####  22-4

- 
-  SDK
- 

####  31-2

- 
- 
- 

---

## 4. API 

### 4.1 

```typescript
import Anthropic from '@anthropic-ai/sdk';

// 
const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
  baseURL: 'https://api.anthropic.com', // 
  timeout: 60000 //  10 
});

// 
const models = await client.models.list();
console.log(models.data);
```

### 4.2 

#### 

```typescript
const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  messages: [{
    role: 'user',
    content: ''
  }]
});

console.log(message.content[0].type); // 'text'
console.log(message.content[0].text); // 
```

#### /PDF

```typescript
const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  messages: [{
    role: 'user',
    content: [
      {
        type: 'text',
        text: ''
      },
      {
        type: 'image',
        source: {
          type: 'base64',
          media_type: 'image/png',
          data: 'iVBORw0KGgoAAAANSUhEUg...' // base64 
        }
      }
    ]
  }]
});
```

### 4.3 

#### 

```typescript
const stream = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  messages: [{ role: 'user', content: '' }],
  stream: true
});

for await (const event of stream) {
  switch (event.type) {
    case 'text_block':
      console.log('');
      break;
    case 'content_block_delta':
      console.log(':', event.delta.text);
      break;
    case 'message_stop':
      console.log('');
      break;
  }
}
```

####  Stream Helper

```typescript
const stream = client.messages.stream({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  messages: [{ role: 'user', content: '' }]
})
  .on('text', (text) => {
    console.log(':', text);
  })
  .on('error', (error) => {
    console.error(':', error);
  })
  .on('finalMessage', (message) => {
    console.log(':', message);
  });

await stream.finalMessage();
```

### 4.4 Tool Use

#### 

```typescript
import { z } from 'zod';
import { betaZodTool } from '@anthropic-ai/sdk/helpers/beta/zod';

//  1 Zod
const searchTool = betaZodTool({
  name: 'search_code',
  description: '',
  inputSchema: z.object({
    query: z.string().describe(''),
    file_type: z.string().optional().describe('')
  }),
  run: async (input) => {
    // 
    const results = await searchInCodebase(input.query, input.file_type);
    return JSON.stringify(results);
  }
});

//  2 JSON Schema
const searchTool2: Anthropic.Tool = {
  name: 'search_code',
  description: '',
  input_schema: {
    type: 'object',
    properties: {
      query: {
        type: 'string',
        description: ''
      },
      file_type: {
        type: 'string',
        description: ''
      }
    },
    required: ['query']
  }
};
```

#### 

```typescript
//  1
const finalMessage = await client.beta.messages.toolRunner({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  messages: [{ role: 'user', content: ' TypeScript  "API" ' }],
  tools: [searchTool]
});

//  2
const response = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  messages: [{ role: 'user', content: '' }],
  tools: [searchTool]
});

// 
let currentMessages = [{ role: 'user', content: '' }];

for (const block of response.content) {
  if (block.type === 'tool_use') {
    // 
    const result = await executeTool(block.name, block.input);

    // 
    const toolResponse = await client.messages.create({
      model: 'claude-sonnet-4-5-20250929',
      max_tokens: 8192,
      messages: [
        ...currentMessages,
        { role: 'assistant', content: response.content },
        {
          role: 'user',
          content: [{
            type: 'tool_result',
            tool_use_id: block.id,
            content: result
          }]
        }
      ]
    });
  }
}
```

### 4.5 Token 

```typescript
//  token 
const tokenCount = await client.messages.countTokens({
  model: 'claude-sonnet-4-5-20250929',
  messages: [
    { role: 'user', content: '...' }
  ]
});

console.log(' tokens:', tokenCount.input_tokens);

// 
const message = await client.messages.create({...});
console.log(' tokens:', message.usage.input_tokens);
console.log(' tokens:', message.usage.output_tokens);
```

### 4.6  (Extended Thinking)

####  Extended Thinking

Extended Thinking  Claude 

-  token 
-  `thinking` 
- 

#### 

```typescript
const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 3200,
  // 
  thinking: {
    type: 'enabled',
    budget_tokens: 1600  //  token 
  },
  messages: [{
    role: 'user',
    content: '...'
  }]
});

// 
for (const block of message.content) {
  if (block.type === 'thinking') {
    console.log(':', block.thinking);
    console.log(':', block.signature);
  } else if (block.type === 'text') {
    console.log(':', block.text);
  }
}
```

****
- `budget_tokens`:  token 
  - 1024 tokens
  -  `max_tokens`
  -  `max_tokens` 
- `type`:  `'enabled'` 

####  Thinking

```typescript
const stream = client.messages.stream({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 3200,
  thinking: {
    type: 'enabled',
    budget_tokens: 1600
  },
  messages: [{
    role: 'user',
    content: ''
  }]
})
  .on('thinking', (thinking) => {
    // 
    process.stdout.write(thinking);
  })
  .on('text', (text) => {
    // 
    process.stdout.write(text);
  })
  .on('signature', (signature) => {
    // 
    console.log('\n:', signature);
  })
  .on('error', (error) => {
    console.error(':', error);
  });

const finalMessage = await stream.finalMessage();
console.log('\n:', finalMessage);
```

#### 

```typescript
let thinkingState = 'not-started';

const stream = client.messages.stream({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 3200,
  thinking: { type: 'enabled', budget_tokens: 1600 },
  messages: [{ role: 'user', content: '' }]
})
  .on('thinking', (thinking) => {
    if (thinkingState === 'not-started') {
      console.log(':\n---------');
      thinkingState = 'started';
    }
    process.stdout.write(thinking);
  })
  .on('text', (text) => {
    if (thinkingState !== 'finished') {
      console.log('\n\n:\n-----');
      thinkingState = 'finished';
    }
    process.stdout.write(text);
  });

await stream.finalMessage();
```

#### 

** Extended Thinking **
1. ****
2. ****
3. ****
4. **** bug 
5. ****

****
1. 
2. 
3. 

#### 

```typescript
//  thinking budget
function calculateThinkingBudget(complexity: 'low' | 'medium' | 'high'): number {
  const budgets = {
    low: 1024,      // 
    medium: 2048,   // 
    high: 4096      // 
  };
  return budgets[complexity];
}

const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  thinking: {
    type: 'enabled',
    budget_tokens: calculateThinkingBudget('high')
  },
  messages: [{ role: 'user', content: complexQuestion }]
});
```

####  Thinking

```typescript
// thinking 
const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  messages: [{ role: 'user', content: '' }]
});

// 
const message2 = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 1024,
  thinking: { type: 'disabled' },
  messages: [{ role: 'user', content: '' }]
});
```

---

## 6. 

### 6.1 

```typescript
import {
  APIError,
  APIConnectionError,
  RateLimitError,
  AuthenticationError
} from '@anthropic-ai/sdk';

try {
  const message = await client.messages.create({...});
} catch (error) {
  if (error instanceof APIConnectionError) {
    console.error(':', error.message);
  } else if (error instanceof RateLimitError) {
    console.error('');
  } else if (error instanceof AuthenticationError) {
    console.error('API ');
  } else if (error instanceof APIError) {
    console.error('API :', error.message);
    console.error(':', error.status);
    console.error(':', error.error);
  }
}
```

### 6.2 

SDK 

```typescript
const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
  maxRetries: 3, //  2
  timeout: 60000
});
```

### 6.3 

#### 1. 

```typescript
const message = await client.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 8192,
  system: '',
  messages: [
    {
      role: 'user',
      content: ''
    }
  ],
  // 
  cache_control: {
    type: 'ephemeral',
    ttl: '5m'
  }
});
```

#### 2. 

```typescript
//  Message Batches API
const batch = await client.messages.batches.create({
  requests: [
    {
      custom_id: 'request-1',
      params: {
        model: 'claude-sonnet-4-5-20250929',
        max_tokens: 1024,
        messages: [{ role: 'user', content: ' 1' }]
      }
    },
    {
      custom_id: 'request-2',
      params: {
        model: 'claude-sonnet-4-5-20250929',
        max_tokens: 1024,
        messages: [{ role: 'user', content: ' 2' }]
      }
    }
  ]
});

// 
const results = await client.messages.batches.results(batch.id);
for await (const result of results) {
  console.log(result);
}
```

### 6.4 

#### 1. API 

```typescript
//  
const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY
});

//  
const client = new Anthropic({
  apiKey: 'sk-ant-xxx...' // 
});
```

#### 2. 

```typescript
// 
function sanitizeUserInput(input: string): string {
  // 
  return input
    .replace(/ {
    const fs = await import('fs/promises');
    await fs.writeFile(input.filePath, input.content, 'utf-8');
    return '';
  }
});

// 
async function codeAssistant(userRequest: string) {
  const finalMessage = await client.beta.messages.toolRunner({
    model: 'claude-sonnet-4-5-20250929',
    max_tokens: 8192,
    system: '',
    messages: [{ role: 'user', content: userRequest }],
    tools: [readFileTool, writeFileTool]
  });

  return finalMessage;
}

// 
const result = await codeAssistant(' src/index.js ');
console.log(result.content);
```

### 8.2 

```typescript
async function streamingCodeAssistant(userRequest: string) {
  const stream = client.messages.stream({
    model: 'claude-sonnet-4-5-20250929',
    max_tokens: 8192,
    system: '',
    messages: [{ role: 'user', content: userRequest }],
    tools: [readFileTool, writeFileTool]
  })
    .on('text', (text) => {
      process.stdout.write(text);
    })
    .on('toolUse', (toolUse) => {
      console.log('\n[]', toolUse.name, toolUse.input);
    })
    .on('error', (error) => {
      console.error('\n[]', error);
    });

  const finalMessage = await stream.finalMessage();
  return finalMessage;
}
```

### 8.3 

```typescript
import * as readline from 'readline';

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

async function askQuestion(query: string): Promise {
  return new Promise(resolve => {
    rl.question(query, (answer) => {
      resolve(answer);
    });
  });
}

async function interactiveChat() {
  const messages: Anthropic.MessageParam[] = [];

  console.log('=== Closer Code  ===');
  console.log(' "quit" \n');

  while (true) {
    const userInput = await askQuestion(': ');

    if (userInput.toLowerCase() === 'quit') {
      break;
    }

    messages.push({
      role: 'user',
      content: userInput
    });

    const stream = client.messages.stream({
      model: 'claude-sonnet-4-5-20250929',
      max_tokens: 8192,
      messages
    })
      .on('text', (text) => {
        process.stdout.write(text);
      })
      .on('finalMessage', (msg) => {
        messages.push({
          role: 'assistant',
          content: msg.content
        });
      });

    await stream.finalMessage();
    console.log('\n');
  }

  rl.close();
}

interactiveChat();
```

### 8.4  Extended Thinking

 Extended Thinking 

```typescript
import Anthropic from '@anthropic-ai/sdk';
import { betaZodTool } from '@anthropic-ai/sdk/helpers/beta/zod';
import { z } from 'zod';

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY
});

// 
const analyzeFileTool = betaZodTool({
  name: 'analyze_file',
  description: '',
  inputSchema: z.object({
    filePath: z.string().describe(''),
    analysisType: z.enum(['security', 'performance', 'readability', 'all'])
      .describe('')
  }),
  run: async (input) => {
    const fs = await import('fs/promises');
    try {
      const content = await fs.readFile(input.filePath, 'utf-8');
      return {
        success: true,
        file: input.filePath,
        content: content.slice(0, 5000), // 
        analysisType: input.analysisType
      };
    } catch (error) {
      return {
        success: false,
        error: (error as Error).message
      };
    }
  }
});

// 
class CodeReviewAssistant {
  private client: Anthropic;
  private model: string;

  constructor() {
    this.client = new Anthropic({
      apiKey: process.env.ANTHROPIC_API_KEY
    });
    this.model = 'claude-sonnet-4-5-20250929';
  }

  //  Extended Thinking 
  async deepAnalysis(userRequest: string, complexity: 'low' | 'medium' | 'high' = 'high') {
    const thinkingBudgets = {
      low: 1024,
      medium: 2048,
      high: 4096
    };

    console.log(`\n===  (Thinking Budget: ${thinkingBudgets[complexity]} tokens) ===\n`);

    let thinkingState = 'not-started';
    let thinkingContent = '';

    const stream = this.client.messages.stream({
      model: this.model,
      max_tokens: 8192,
      thinking: {
        type: 'enabled',
        budget_tokens: thinkingBudgets[complexity]
      },
      system: `
1. 
2. 
3. 
4. 
5. `,
      messages: [{ role: 'user', content: userRequest }],
      tools: [analyzeFileTool]
    })
      .on('thinking', (thinking) => {
        if (thinkingState === 'not-started') {
          console.log(' ...\n---');
          thinkingState = 'started';
        }
        thinkingContent += thinking;
        process.stdout.write(thinking);
      })
      .on('text', (text) => {
        if (thinkingState !== 'finished') {
          console.log('\n\n---\n :\n---');
          thinkingState = 'finished';
        }
        process.stdout.write(text);
      })
      .on('toolUse', (toolUse) => {
        console.log('\n\n :', toolUse.name);
        console.log(':', JSON.stringify(toolUse.input, null, 2));
      })
      .on('error', (error) => {
        console.error('\n :', error);
      });

    const finalMessage = await stream.finalMessage();

    console.log('\n\n===  ===');
    console.log(`: ${thinkingContent.length} `);
    console.log(`Token : =${finalMessage.usage.input_tokens}, =${finalMessage.usage.output_tokens}`);

    return {
      finalMessage,
      thinkingContent
    };
  }

  //  Extended Thinking
  async quickAnalysis(userRequest: string) {
    console.log('\n===  ===\n');

    const finalMessage = await this.client.beta.messages.toolRunner({
      model: this.model,
      max_tokens: 4096,
      system: '',
      messages: [{ role: 'user', content: userRequest }],
      tools: [analyzeFileTool]
    });

    console.log(' ');
    console.log(`Token : =${finalMessage.usage.input_tokens}, =${finalMessage.usage.output_tokens}`);

    return finalMessage;
  }
}

// 
async function main() {
  const assistant = new CodeReviewAssistant();

  //  1: 
  console.log('\n 1: ');
  await assistant.deepAnalysis(
    ' src/auth/login.ts SQLXSS',
    'high'
  );

  // 
  await new Promise(resolve => setTimeout(resolve, 2000));

  //  2: 
  console.log('\n\n 2: ');
  await assistant.quickAnalysis(' src/utils/helpers.ts ');

  //  3: 
  console.log('\n\n 3: ');
  const result = await assistant.deepAnalysis(
    '',
    'high'
  );

  // 
  if (result.thinkingContent) {
    console.log('\n :  result.thinkingContent');
  }
}

// 
if (require.main === module) {
  main().catch(console.error);
}

export { CodeReviewAssistant };
```

#### 

```bash
$ npm run code-review

===  (Thinking Budget: 4096 tokens) ===

 ...
---
...


1. 
2. 
3. 


- 
- 
- 

...
---
 :
---


1. **SQL **:  45 ...
2. ****:  HTTP-only cookies...
3. ****: ...

===  ===
: 1243 
Token : =3456, =789
```

#### 

1. ****:  thinking budget
2. ****: 
3. ****: 
4. ****: 

#### 

- ****:  `high`  thinking budget (4096+)
- ****:  `medium`  (2048 tokens)
- ****: 

---

 `@anthropic-ai/sdk` 

1. ** 70-80%**
2. **** TypeScript 
3. ****
4. **** SSE
5. ****toolRunner 
6. ****
7. **Extended Thinking **
8. ****


-   SDK
-  
-  
-  

---

****: 1.1.0
****: 2025-01-18
****: Closer Code 

****:
- v1.1.0 (2025-01-18):  Extended Thinking 
- v1.0.0 (2025-01-17):  API 

****:
- [Anthropic TypeScript SDK ](../ref_repo/anthropic-sdk-typescript/api.md)
- [Messages API ](https://docs.anthropic.com/claude/reference/messages-post)
- [Closer Code  README](./README.md)

Web Proxy Viewer  |  New URL  |  Original Page