mirror of
https://github.com/codeaashu/claude-code.git
synced 2026-04-08 22:28:48 +03:00
claude-code
This commit is contained in:
85
web/lib/api.ts
Normal file
85
web/lib/api.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { Message } from "./types";
|
||||
|
||||
const getApiUrl = () =>
|
||||
process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3001";
|
||||
|
||||
export interface StreamChunk {
|
||||
type: "text" | "tool_use" | "tool_result" | "done" | "error";
|
||||
content?: string;
|
||||
tool?: {
|
||||
id: string;
|
||||
name: string;
|
||||
input?: Record<string, unknown>;
|
||||
result?: string;
|
||||
is_error?: boolean;
|
||||
};
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export async function* streamChat(
|
||||
messages: Pick<Message, "role" | "content">[],
|
||||
model: string,
|
||||
signal?: AbortSignal
|
||||
): AsyncGenerator<StreamChunk> {
|
||||
const response = await fetch("/api/chat", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ messages, model, stream: true }),
|
||||
signal,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const err = await response.text();
|
||||
yield { type: "error", error: err };
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = response.body?.getReader();
|
||||
if (!reader) {
|
||||
yield { type: "error", error: "No response body" };
|
||||
return;
|
||||
}
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = "";
|
||||
|
||||
try {
|
||||
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.startsWith("data: ")) {
|
||||
const data = line.slice(6).trim();
|
||||
if (data === "[DONE]") {
|
||||
yield { type: "done" };
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const chunk = JSON.parse(data) as StreamChunk;
|
||||
yield chunk;
|
||||
} catch {
|
||||
// skip malformed chunks
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
|
||||
yield { type: "done" };
|
||||
}
|
||||
|
||||
export async function fetchHealth(): Promise<boolean> {
|
||||
try {
|
||||
const res = await fetch(`${getApiUrl()}/health`, { cache: "no-store" });
|
||||
return res.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user