summaryrefslogtreecommitdiff
path: root/src/claude.ts
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-07-23 05:41:58 +0700
committerpolwex <polwex@sortug.com>2025-07-23 05:41:58 +0700
commit9766782648617e232fbc4e40ea96a0e567c7cc73 (patch)
tree084943c250a0ad6d7a3227a6b10b237ee07b2388 /src/claude.ts
parent42dd99bfac9777a4ecc6700b87edf26a5c984de6 (diff)
something like that. man anthropic is old
Diffstat (limited to 'src/claude.ts')
-rw-r--r--src/claude.ts104
1 files changed, 45 insertions, 59 deletions
diff --git a/src/claude.ts b/src/claude.ts
index 2a56bc1..629f9c2 100644
--- a/src/claude.ts
+++ b/src/claude.ts
@@ -1,26 +1,21 @@
import Claude from "@anthropic-ai/sdk";
import { RESPONSE_LENGTH } from "./logic/constants";
-import type {
- AIModelAPI,
- ChatMessage,
- OChoice,
- OChunk,
- OMessage,
-} from "./types";
+import type { AIModelAPI, ChatMessage } from "./types";
import { BOOKWORM_SYS } from "./prompts";
import type { AsyncRes } from "sortug";
+import type { MessageCreateParamsStreaming } from "@anthropic-ai/sdk/resources";
type Message = Claude.Messages.MessageParam;
export default class ClaudeAPI implements AIModelAPI {
- private model: string = "claude-3-7-sonnet-20250219";
+ private model: string = "claude-opus-4-20250514";
tokenizer: (text: string) => number;
maxTokens: number;
// model: string = "claude-3-5-sonnet-20241022";
constructor(
+ model: string,
maxTokens = 200_000,
tokenizer: (text: string) => number = (text) => text.length / 3,
- model?: string,
) {
this.maxTokens = maxTokens;
this.tokenizer = tokenizer;
@@ -36,30 +31,17 @@ export default class ClaudeAPI implements AIModelAPI {
});
}
- private mapMessagesR1(input: ChatMessage[]): Message[] {
- return input.reduce((acc: Message[], m, i) => {
- const prev = acc[i - 1];
- const role: any = m.author === "claude" ? "assistant" : "user";
- const msg = { role, content: m.text };
- if (prev?.role === role) acc[i - 1] = msg;
- else acc = [...acc, msg];
- return acc;
- }, []);
- }
-
- public async send(sys: string, input: ChatMessage[]) {
- const messages = this.mapMessages(input);
+ public async send(input: string | ChatMessage[], sys?: string) {
+ const msgs: ChatMessage[] =
+ typeof input === "string"
+ ? [{ author: "user", text: input, sent: 0 }]
+ : input;
+ const messages = this.mapMessages(msgs);
const truncated = this.truncateHistory(messages);
- const res = await this.apiCall(sys, truncated);
+ const res = await this.apiCall(truncated, sys);
return res;
}
- public async sendR1(input: ChatMessage[]) {
- const messages = this.mapMessagesR1(input);
- const truncated = this.truncateHistory(messages);
- const res = await this.apiCall("", truncated, true);
- return res;
- }
public async sendDoc(data: string) {
const sys = BOOKWORM_SYS;
const msg: Message = {
@@ -75,24 +57,22 @@ export default class ClaudeAPI implements AIModelAPI {
},
],
};
- const res = await this.apiCall(sys, [msg]);
+ const res = await this.apiCall([msg], sys);
return res;
}
public async stream(
- sys: string,
- input: ChatMessage[],
+ input: string | ChatMessage[],
handle: (c: any) => void,
+ sys?: string,
) {
- const messages = this.mapMessages(input);
+ const msgs: ChatMessage[] =
+ typeof input === "string"
+ ? [{ author: "user", text: input, sent: 0 }]
+ : input;
+ const messages = this.mapMessages(msgs);
const truncated = this.truncateHistory(messages);
- await this.apiCallStream(sys, truncated, handle);
- }
-
- public async streamR1(input: ChatMessage[], handle: (c: any) => void) {
- const messages = this.mapMessagesR1(input);
- const truncated = this.truncateHistory(messages);
- await this.apiCallStream("", truncated, handle, true);
+ await this.apiCallStream(truncated, handle, sys);
}
private truncateHistory(messages: Message[]): Message[] {
@@ -108,26 +88,30 @@ export default class ClaudeAPI implements AIModelAPI {
// TODO
// https://docs.anthropic.com/en/api/messages-examples#putting-words-in-claudes-mouth
private async apiCall(
- system: string,
messages: Message[],
- isR1: boolean = false,
- ): Promise<AsyncRes<string[]>> {
+ system?: string,
+ ): Promise<AsyncRes<string>> {
try {
const claud = new Claude();
- // const list = await claud.models.list();
- // console.log(list.data);
- const res = await claud.messages.create({
+ const params = {
model: this.model,
max_tokens: RESPONSE_LENGTH,
- system,
messages,
- });
- return {
- ok: res.content.reduce((acc: string[], item) => {
- if (item.type === "tool_use") return acc;
- else return [...acc, item.text];
- }, []),
};
+ const res = await claud.messages.create(
+ system ? { ...params, system } : params,
+ );
+ const resm: string = res.content.reduce((acc: string, item) => {
+ if (item.type === "tool_use") return acc;
+ else if (item.type === "text") return `${acc}\n${item.text}`;
+ else return acc;
+ }, "");
+ // const resm = res.content.reduce((acc: string[], item) => {
+ // if (item.type === "tool_use") return acc;
+ // else if (item.type === "text") return [...acc, item.text]
+ // else return acc;
+ // }, []);
+ return { ok: resm };
} catch (e) {
console.log(e, "error in claude api");
return { error: `${e}` };
@@ -135,20 +119,22 @@ export default class ClaudeAPI implements AIModelAPI {
}
private async apiCallStream(
- system: string,
messages: Message[],
handle: (c: any) => void,
- isR1: boolean = false,
+ system?: string,
): Promise<void> {
try {
const claud = new Claude();
- const stream = await claud.messages.create({
+ const params = {
model: this.model,
max_tokens: RESPONSE_LENGTH,
- system,
messages,
- stream: true,
- });
+ stream: true as true,
+ };
+ const fparams: MessageCreateParamsStreaming = system
+ ? { ...params, system }
+ : params;
+ const stream = await claud.messages.create(fparams);
for await (const part of stream) {
if (part.type === "message_start") continue;